Full Code of markh794/mhvtl for AI

master e942484250dd cached
155 files
1.6 MB
556.1k tokens
1450 symbols
1 requests
Download .txt
Showing preview only (1,732K chars total). Download the full file or copy to clipboard to get everything.
Repository: markh794/mhvtl
Branch: master
Commit: e942484250dd
Files: 155
Total size: 1.6 MB

Directory structure:
gitextract_1xsiiwpt/

├── .clang-format
├── .github/
│   └── workflows/
│       └── codeql.yml
├── .gitignore
├── COPYING
├── ChangeLog
├── INSTALL
├── Makefile
├── README
├── ccan/
│   └── ccan/
│       └── crc32c/
│           ├── _info
│           ├── benchmark/
│           │   ├── Makefile
│           │   └── bench.c
│           ├── crc32c.c
│           ├── crc32c.h
│           └── test/
│               ├── api-crc32c.c
│               └── run-crc32c.c
├── config.mk
├── doc/
│   ├── 4_library_example/
│   │   ├── device.conf
│   │   ├── library_contents.10
│   │   ├── library_contents.20
│   │   ├── library_contents.30
│   │   ├── library_contents.40
│   │   └── mhvtl.conf
│   └── index.html
├── etc/
│   ├── .gitignore
│   ├── Makefile
│   ├── generate_device_conf.in
│   ├── generate_library_contents.in
│   ├── library_contents.sample
│   ├── mhvtl-load-modules.service.in
│   ├── mhvtl.conf.in
│   ├── mhvtl.target
│   ├── vtllibrary@.service.in
│   └── vtltape@.service.in
├── include/
│   ├── common/
│   │   ├── logging.h
│   │   ├── mhvtl_scsi.h
│   │   ├── vtl_common.h
│   │   ├── vtl_u.h
│   │   └── vtltape_pem.h
│   ├── mhvtl_log.h
│   ├── mode.h
│   ├── smc.h
│   ├── spc.h
│   ├── ssc.h
│   ├── utils/
│   │   ├── be_byteshift.h
│   │   ├── lzoconf.h
│   │   ├── lzodefs.h
│   │   ├── mhvtl_list.h
│   │   ├── mhvtl_update.h
│   │   ├── minilzo.h
│   │   ├── q.h
│   │   ├── security_protocol.h
│   │   └── subprocess.h
│   ├── vtlcart.h
│   └── vtllib.h
├── kernel/
│   ├── .gitignore
│   ├── Makefile
│   ├── backport.h
│   ├── config.sh
│   ├── fetch.c
│   ├── fetch24.c
│   ├── fetch26.c
│   ├── fetch27.c
│   ├── fetch50.c
│   └── mhvtl.c
├── man/
│   ├── Makefile
│   ├── device.conf.5.in
│   ├── dump_tape.1.in
│   ├── edit_tape.1.in
│   ├── generate_device_conf.1.in
│   ├── generate_library_contents.1.in
│   ├── library_contents.5.in
│   ├── make_vtl_media.1.in
│   ├── mhvtl.conf.5.in
│   ├── mhvtl_kernel_mod_build.1.in
│   ├── mktape.1.in
│   ├── preload_tape.1.in
│   ├── tapeexerciser.1.in
│   ├── update_device.conf.1.in
│   ├── vtlcmd.1.in
│   ├── vtllibrary.1.in
│   └── vtltape.1.in
├── mhvtl-utils.spec
├── scripts/
│   ├── 70-persistent-generic.rules
│   ├── 70-persistent-tape.rules
│   ├── Makefile
│   ├── NetBackup/
│   │   ├── drive_stats.pl
│   │   └── vlt_endeject_notify.pl
│   ├── build-persistent-tape-rules.sh
│   ├── centos_configure.sh
│   ├── checkarch.sh
│   ├── checkpatch.pl
│   ├── lio_target_passthru.sh
│   ├── mhvtl-1.4.ebuild
│   ├── rescan-scsi-bus.sh
│   ├── start-mhvtl-scst.sh
│   ├── stgt-target-setup.conf
│   ├── test_lbp.sh
│   └── update_device.conf.in
├── tcopy/
│   ├── Makefile
│   ├── pathnames.h
│   ├── tcopy.1
│   └── tcopy.c
├── todo
├── usr/
│   ├── .gitignore
│   ├── Makefile
│   ├── cmd/
│   │   ├── dump_messageQ.c
│   │   ├── edit_tape.c
│   │   ├── make_scsi_dev
│   │   ├── make_vtl_media.in
│   │   ├── mhvtl-device-conf-generator.c
│   │   ├── mhvtl_kernel_mod_build.in
│   │   ├── mktape.c
│   │   ├── tape_util.c
│   │   ├── tapeexerciser.c
│   │   ├── vtlcmd.c
│   │   ├── vtllibrary.c
│   │   └── vtltape.c
│   ├── mhvtl_io.c
│   ├── mhvtl_log.c
│   ├── mode.c
│   ├── pm/
│   │   ├── ait_pm.c
│   │   ├── default_smc_pm.c
│   │   ├── default_ssc_pm.c
│   │   ├── hp_smc_pm.c
│   │   ├── hp_ultrium_pm.c
│   │   ├── ibm_03592_pm.c
│   │   ├── ibm_smc_pm.c
│   │   ├── overland_pm.c
│   │   ├── quantum_dlt_pm.c
│   │   ├── scalar_pm.c
│   │   ├── spectra_pm.c
│   │   ├── stk9x40_pm.c
│   │   ├── stklxx_pm.c
│   │   ├── t10000_pm.c
│   │   └── ult3580_pm.c
│   ├── smc.c
│   ├── spc.c
│   ├── ssc.c
│   ├── utils/
│   │   ├── README.LZO
│   │   ├── crc32c.c
│   │   ├── mhvtl_update.c
│   │   ├── minilzo.c
│   │   ├── q.c
│   │   ├── reed-solomon.c
│   │   ├── subprocess.c
│   │   └── validate_crc.c
│   ├── vtl_cart_type.c
│   ├── vtlcart.c
│   ├── vtlcart_v1.c
│   ├── vtlcart_v1_mtr.c
│   └── vtllib.c
├── vagrant/
│   ├── README.MD
│   ├── Vagrantfile
│   └── install.sh
└── webgui/
    └── index.php

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
BasedOnStyle: LLVM
IndentWidth: 4
UseTab: Always
TabWidth: 4
ColumnLimit: 0

# --- Includes ---
IncludeBlocks: Preserve
SortIncludes: false

# --- Initializers ---
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: true
AllowShortLoopsOnASingleLine: true

# --- Alignement ---
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignConsecutiveMacros: true
BinPackArguments: true
BinPackParameters: true

================================================
FILE: .github/workflows/codeql.yml
================================================
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ master ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ master ]
  schedule:
    - cron: '43 6 * * 5'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'cpp' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Learn more about CodeQL language support at https://git.io/codeql-language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v1
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v1

    # ℹ️ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v1


================================================
FILE: .gitignore
================================================
*.ko
*.o
*~
/cscope.*
/kernel/.*.ko.cmd
/kernel/.*.o.cmd
/kernel/.tmp_versions/
/kernel/mhvtl.mod.c
/kernel/Module.symvers
/kernel/modules.order
/kernel/config.h
/scripts/update_device.conf
/man/*.1
/man/*.5
/tcopy/tcopy
local.mk
mhvtl_kernel.tgz
/usr/mhvtl_kernel_mod_build

# Vagrant specific files
/vagrant/.vagrant
/vagrant/*.log


================================================
FILE: COPYING
================================================

 Note that the GPL below is copyrighted by the Free Software
 Foundation, but the instance of code that it refers to
 (the 'mhvtl' user-space and kernel) is copyrighted by me and
 others who actually wrote it.

 Also note that the only valid version of the GPL as far as the kernel
 is concerned is _this_ particular version of the license (ie v2, not
 v2.2 or v3.x or whatever), unless explicitly otherwise stated.

			Mark Harvey

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

		    GNU GENERAL PUBLIC LICENSE
		       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
                       51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

		    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

			    NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

		     END OF TERMS AND CONDITIONS

	    How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.


================================================
FILE: ChangeLog
================================================
* Tue Mar 10 17:30:00 AEST 2026 Mark Harvey <markh794@gmail.com>
- A hugh patch set to add LTFS support. Many thanks to QuentinLoriaux

* Tue Mar 10 16:30:00 AEST 2026 Mark Harvey <markh794@gmail.com>
- mhvtl.ko: Various updates to keep track of recent mainline changes
- add GET/SET TIMESTAMP OP code support
- fix for Logical Block Protection

* Mon Mar 10 12:11:00 AEST 2025 Mark Harvey <markh794@gmail.com>
- Remove reference to Nutanix as I no longer work there
- Implement Logical Block Protection for LTO emulations
- mhvtl.ko: Update to support recent kernel changes
- more 32/64bit cast fixes (Raspberry-Pi) & x86_64
- Fix issue with helper script creating WORM media (Thanks Gaurav Malhotra)
- Initial LTO-9 emulation (Thanks Gwen Dawes)
- daemon exit strategy change - reduce possibility of shutdown during inflight I/O
- Fix READ POSITION
- Implement VHF log page
- Reduce calls to fflush() unless in debug mode

* Fri Mar 10 16:30:00 AEST 2023 Mark Harvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- review of all utilities and use '-m <barcode>' the standard option
- Add support for 'INQUIRY_DATA_HAS_CHANGED'
- Added 'Extended Inquiry Data VPD page for Ultrium
- Add SELinux ACL so systemctl scripts will work if SELinux is enforcing
- mhvtl.ko: Various improvements to suit recent kernel changes (thanks Lee Duncan and Tamas Revesz)
- mhvtl.ko: Change initiator ID from 15 to -1 (resolves conflict if target also configured with ID 15)
- mhvtl.ko: Remove printk in favour of pr_* calls
- pre-package mhvtl.ko source into /usr/lib/firmware/mhvtl/ and add wrapper script 'mhvtl_kernel_mod_build' to extract, compile and install
- Various 64bit/32bit casts fixed.
- Updated Vagrant to use AlmaLinux, RockyLinux, CentOS, OpenSuse, Ubuntu

* Thu Mar 10 10:30:00 AEST 2022 Mark Harvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- Updated default drives in library 10 from LTO4/LTO5 to LTO6 & LTO8
- Added initial support for Data Integrity Validation (via Logical Block Protection) - IBM LTO6,LTO7 & LTO8 with this release.
- mhvtl.ko: Various updates to match the latest kernels
- Additional checks for Vagrant build on CentOS, Ubuntu and OpenSUSE
- Improve tape load/unload handshake to make it more robust
- Improve handling of missing slot numbers in library_contents.xx
- Makefile - Move variables to a common location (config.mk)
- SEND DIAGNOSTICS: Implement basic sanity check for SSC devices
- VERIFY(6) op code support
- Update install instructions with sg3_utils vs sg3-utils package names
- LTO-6 media load to match LTO standards (LTO8 cannot read LTO6 media)
- New utility 'preload_tape' bypassing need to write via /dev/st*
- Add missing 'ENCRYPTION capable' bit for LTO6, 7 & 8 media
- systemd device config: Best effort, log errors via klog
- Obligatory spelling fixes
- Bump version to 1.7 : Beginning of LBP, VERIFY(6) and SEND DIAGNOSTICS support

* Thu Oct 07 10:40:00 AEST 2021 Mark Harvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- rename list.h to avoid generic name conflict
- rename scsi.h to avoid generic name conflict
- rename log.h to avoid generic name conflict
- Exclude __builtin_cpu_supports() on non x86_64 CPU types
- Fix spelling of retrieving
- mhvtl.ko: Define SG_SEGMENT_SZ only if not defined
- Increase default kmem_cache bounce buffer size to 64k
- mhvtl.ko: kernel module oops on PPC
- mhvtl.ko: Log errors if they occur
- mhvtl.ko: Correct compiler warning about printf var sizes
- mhvtl.ko: Simplify file_inode()
- mhvtl.ko: Use _safe version of list_for_each_entry
- mhvtl.ko: Limit number of outstanding queued commands
- mhvtl.ko: Log minor number with other ioctl info
- mhvtl.ko: clean up noisy logging at level 2
- mhvtl.ko: Initialise outstanding op struct before adding to list
- mktape: Set default version string based from MHVTL_VERSION
- Update LTO-8 media denisty codes
- Security Protocol OUT: Fix null pointer check
- Fix routine to extract barcode from string
- Fix typos in mktape man page
- dump_tape: Fix segfault due to local variable conflict
- Use bounce buffer if tape block size is larger than request buffer
- Remove unused scsi_host_template field
- mhvtl.ko: Compile on RedHat 8.x kernel
- mhvtl.ko: reinstate HAVE_UNLOCKED_IOCTL
- mhvtl.ko: Remove reference to DRIVER_SENSE
- Update function names with 'mhvtl_' prefix
- Update kernel /sys/ location to suit new pseudo name space
- OOM: /proc/<pid>/oom_adj is deprecated. Using oom_score_adj.
- systemd: Update Makefile to include systemd install path
- mhvtl.spec: Update to build a package on CentOS8

* Tue Mar 10 09:00:00 AEST 2020 Mark Harvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- Fix kernel module oops/panic due to race between placing OP ready for user space before all variable were initialised
- Add ccan version of crc32c routine which includes CPU optimisations for sse4.2 capabile CPUs

* Sun Oct 06 12:20:00 AEST 2019 Mark Harvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- Fix kernel copy_to_user()/copy_from_user() to use white-listed buffer
- Fix kernel compile for 5.0+ kernels

* Wed Apr 10 10:30:30 AEST 2019 Mark Marvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- Fix long standing bug on media unload
- Added CRC32 checks for each block written/read
- allow kernel module to compile on 5.0 kernels
- Add example on how to configure LIO pscsi (passthru) driver with mhVTL
- Fix parsing args in dump_tape

* Thu Mar 28 14:30:30 AEST 2019 Mark Marvey <markh794@gmail.com> <mark.harvey@nutanix.com>
- Create virtual media on rpm install
- Fixed a couple typos in spec file (one from several years ago)
- Don’t overwrite /etc/mhvtl/* but install as ‘rpmnew’
- Replace SUSE specific rpm macros with hand crafted ’systemctl’ commands.
- systems-generators dir needed munging for CentOS7
- Include ‘ChangeLog’ as part of the tar ball - the time/date build on man pages is dependant

* Thu Nov 29 15:42:24 PST 2018 Lee Duncan <lduncan@suse.com>
- Many changes to support systemd:
  - Removed /etc/init.d/mhvtl script
  - Config files are now generated at install time, not the first
    time the service is run
  - Created service files and templates, and a generator
  - Updated INSTALL file with sytemd info
  - removed build_library_config and mhvtl init script
  - Updated man pages and doc/index.html
  - Updated make files
  - created generate_device_conf and generate_library_contents, called at
    'make install' time, to take the place of what the init file used to do
  - updated SPEC file for systemd
  - updated example scripts
  - fixed asprintf calls to check return values (to make compiler happy)
  - added some arguments and better arg parsing to vtltape and vtllibray
- moved some .gitignore entries around, to be more local
- Bumped version to 1.5-5
- Fixed config file error in library_contents.* where VERSION was missing

* Thu Sep 7 2014 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.5-2
- Fix vtllibrary segfault using 'default' emulation
- Correct slot mappings for L180/L700 emulation
- Correct slot mappings for SL500 emulation
- Increase max serial number length to 15 chars
- More accurate emulation of IBM TS3100/3200 inquiry page bits
- Fix bug with 'edit_tape' not understanding the 'null' media type

* Thu May 1 2014 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.5-1
- Fix bug with vpd pages 0x80 & 0x83 in library personality modules.

* Sun Apr 13 2014 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.5-0
- Introduce library personality modules - limited emulations
- Resolve bug with more than 1260 slots
- Rename mhvtl bus type so scsi_debug & mhvtl can load together.

* Sun Oct 20 2013 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-10
- Various cleanups due to static code check 'smatch'
- Fix TapeAlert bit offsets
- Return bit/byte offset for sense INVALID FIELD IN CDB/PARAMS
- Fix returned data size when 0 data is requested (kernel module fix)
- SSC - Fix op code 0Fh (read reverse) incorrectly set to 'reserve'
- SMC - Ability to keep library media change persistant across restarts
- SSC - Implement 'read media serial number' op code
- Fix 'make_vtl_media' script to understand IBM 03592 media type

* Thu Aug 29 2013 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-9
- SSC -> MODE SELECT overhaul.
- Sanitize delay values introduced in 1.4-8
- daemons now open /dev/mhvtlXX nodes in exclusive mode
- Code cleanup based on Valgrind - memory leaks and unused file handles
- Correctly set SCSI revision field for T10000B
- SMC -> Adjust behaviour if 'Scalar' library defined
 set 'BarC' field in inquiry page and
 pad "Full Firmware Revision" field with compile time/date

* Sat Jun 29 2013 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-8
- Add additional fields in MAM for multi-partition support capability
- MODE SELECT fixes
- Solaris 11.1 st mode select
- Make virtual media more resilient against disk full conditions
- Add additional error checking between kernel and userspace ioctl
- Add ability to introduce delays in load/unload/position/thread/rewind op codes
- Add 16byte CDB locate command support
- Minor kernel module tweeks - increase timeout & error checking on ioctl()

* Fri Mar 22 2013 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-7
- Add DLT7000/DLT8000 emulation
- Record 'last load' data in MAM
- New utility 'edit_tape' which will allow modificiation of media 'meta data'
- Prevent and log possibility of READ ELEMENT STATUS overflowing data buffer
- Set 'POWERON-RESET' if library re-configured via HUP signal
- Update 'minor' number from 'unsigned char' to 'unsigned int' which removes
 max number of device nodes at 256
- Rework READ ELEMENT STATUS - Simplify code and correct bug where incorrect
 byte count returned.
- Add 'support' for specifying 9x40 and DLT media via barcode suffix
- Update kernel module to prevent overflow if DEF_MAX_MINOR_NO reached.
- Update kernel module to allow up to 1024 minor numbers
- Update kernel module vers to 0.18.12, vers date 20130310-0
- off-by-one fix of compression mode page
- Fix 'READ POSITION' ssc op code
- Helper scripts for NetBackup added
 - drive_stats.pl (parse 'scsi_command' output and email on tape unload)
 - vlt_endeject_notify.pl (NetBackup Vault helper)

* Sat Jan 31 2013 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-6
- Return correct TAPE CAPACITY log page
- Fix overflow TAPE CAPACITY log page
- Fix potential vtltape segfault when 'block position back'
- New utility 'edit_tape' to update virtual media metadata

* Sat Jan 12 2013 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-5
- Added support for LTO-6
- Fix EOM handling
- Fix data returned in TAPE CAPACITY log page

* Thu Sep 13 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-4
- Fix a build issue on older (SLES9) linux distributions
- Silence a compiler warning about uninitialised var 'month' in quantum PM
- Note: 1.4-2 & 1.4-3 never made it as released packages.

* Wed Sep 12 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-3
- Add 'performance' counter to vtllibrary
- Fix off-by-one error in LOG SELECT
- Implement LOG reset via PCR bit in LOG SELECT

* Sat Sep 01 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-2
- Add 'performance' counter to each SCSI op code logged

* Wed Aug 08 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-1
- Bug fix:
  Fix dump_tape to understand new library subdirectory format
  Fix vtlcmd to understand new library subdirectory format

* Wed Aug 01 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.4-0
- Allow 'default' personality module to load all media R/W
- Add IBM half-hight INQUIRY string match
- vtltape: Update log entry regarding media capacity depending on capabilities
- vtltape: Make the backoff algrithm value configurable
- Add SDLT600 & SDLT320 personality module
- mhvtl.ko: Silence install 'depmod' error
- Move standard inquiry info into memory structure
- Default media belonging to a library in a subdir
- Remove kmod-mhvtl.spec
- Rename 'mhvtl' package as 'mhvtl-utils'
- Use ELRepo spec file
- Move 'make install' from RPM to Makefile

* Fri Jun 15 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.3-0
- Move 'on disk' unique functions into its own shared lib (libvtlcart.so)
- HP Ultrium VPD page data update to match HP documentation
- IBM Ultrium VPD page 0xC0 & 0xC1 update to match IBM documentation
- Fix SPIN return status
- Add helper functions for moving media within library
  (in prep for library partition manager)
- Add ability to set/clear APPEND ONLY status from user (vtlcmd)

* Wed Apr 04 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.2-3
- Fix segfault in AIT4 when attempting to access Security Protocol IN/OUT
- No need to fail in virtual media parent directory exists
- Add more descriptive debug messages for log/mode page lookups

* Thu Mar 22 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.2-2
- Changed defaults so fifo is not enabled. If fifo not used, it will
  block writing process (i.e. hang daemons)
- Improved MODE SELECT / SENSE to support 'changeable field bitmaps
- Started implementing ALLOW OVERWRITE support (incomplete)
- Fixed INQUIRY string match for STK T10000A

* Sat Jan 21 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.2-1
- Fix memory leak in lzo decompression routine.

* Fri Jan 20 2012 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.2-0
- Ability to specify zlib or lzo compression.
  via 'vtlcmd' at runtime.
      'vtlcmd <> compression lzo'
      'vtlcmd <> compression zlib'
  /etc/mhvtl/device.conf entry
      ' Compression type: lzo'
      ' Compression type: zlib'

* Sat Dec 24 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.1-1
- Clean up IPC resources when finished with them
- Simplify fifo reference counting
- Start including Scientific Linux patches (Still need to include kmod RPM)
- Fix 'make install' on Ubuntu
- Various log message cleanups

* Sun Oct 09 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.1
- Added real time state notification.
  '-f <fifo name>' (Set in build_library_config)
  Defaults to all daemons using the same 'named pipe'
  Each entry is prefixed with '<index>:' and text to the change of state.
- MODE SENSE for LTO devices update the 'media type' field.
- LOG SENSE page 0x0c (Sequential Access Device Page) updates with valid data

* Sun Sep 11 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.0.1
- Added mode page 25h (vendor specific) for IBM LTO3/4/5
  This allows the Windows IBM Tape Driver to load correctly (connected via
  iSCSI)
- Attempt to correct file permission/ownership when media is created manually
- A HUP signal to the vtllibrary daemon will cause it to re-read its config
  from the /etc/mhvtl/library_contents.XX file. (So you can change the slot
  config without having to re-start the daemon).

* Sun Sep 04 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 1.00.00
- Re-worked MODE SENSE/SELECT data structures into a linked list.
- Re-worked LOG SENSE/SELECT data structures into a linked list.
- Added support for sub-page MODE information.
- Added STK 9x40 drive emulations.
- Removed dead code from kernel driver.
- Add working REPORT DENSITY support to the SSC.
  This change required the personality modules to define the list of supported
  densities. The media density is defined at 'mktape' time.
  Hence, the optional 'media load' rules in device.conf are now redundent
  and not used.
  BUT: The option to load any media into any drive is also gone.

* Sat Jun 25 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.17
- Improvements
  - Kernel module compile warning since 2.6.33
- Bug fixes
  - Test MAP port open before moving media
  - Fix buffer overflow in vtllibrary (product_id)
  - Return correct sense from space op code

* Sun May 22 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.16
- Improvements
  - Cleaning media behaves more like real (IBM LTO4) drive.
  - Implement OPEN/CLOSE IMPORT/EXPORT element OP code (Thanks Sebastian)
  - Kernel module support for 2.6.39 (Thanks Sebastian)
- Bug fixes
  - SPACE op code - Space to end-of-data fixed (Thanks Sebastian)
    This fixes an issue triggered using Oracle Backup
  - REQUEST SENSE - Return correct data.
  - SPOUT - Return check_condition on some error paths
  - Cleaning Media - Return 'not ready' instead of 'good' when loaded
  - Don't write FILEMARKS to WORM or Cleaning media

* Wed May 04 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.15
- Improvements
  - Implemented 'Personality Module' for each drive type
    (many cleanups due to 'PM' change fallout thanks to Sebastian)
  - Increase max barcode length to 16 chars
- Bug fixes
  - Inquiry no longer incorrectly reports support for TrmIOP and CmdQue
  - Fixed block read/writes corruption if 'multiple blocks' specified
  - Fix Device Capabilities mode page - Don't advertise EXCHANGE MEDIUM support

* Thu Mar 17 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.14
- Bug fixes:
  - kernel module build fixes for Linux kernel 2.6.37 and greater
- Improvements
  - Add STK T10000C media/drive support
  - Always log 'fatal' errors
  - Cleanup to mhvtl.spec
  - Catch signals to prevent daemon terminating early.

* Thu Jan 11 2011 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.13
- Bug fixes:
  - SMC read element status. Return correct length.
  - SMC read element status. Handle request for 'any' slot type.
  - SSC log page. Byte-swap Bytes Read/Written.
  - vtltape: Return ILLEGAL REQUEST for unsupported OP codes.
  - Density code updates.
  - Increased sense buffer from 38 bytes to 96 bytes.

* Wed Nov 17 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.12
- Bug fixes:
  - Silence 'which setuidgid' test
  - Fix compile on 2.6.34 kernel
  - ERASE only from BOT
  - Test SPACE '0' blocks/filemarks before moving
  - Fix REQUEST SENSE returned size
  - Implement SILI bit test
  - Check if ERASE WORM media is allowed
  - Only support SPIN/SPOUT for LTO-4/5, T10K and 3592E05/6 drive types
  - Fix REQUEST SENSE page length. Previously only returning 8 bytes.
- Improvements
  - Re-organised code in vtllibrary to use a big jump table
  - Fix LTO5 media density reporting
  - Match HP ULTRIUM 4-SCSI
  - Ability to create DDS specific media
    (still need to find correct density codes for DDS)

* Thu Sep 23 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.11
- Bug fix: Off-by-one if a re-position & then overwrite a filemark.
  Caused TSM & HP Dataprotector all sorts of problems.
- Export kernel module 'major' number via /sys/bus/pseudo/drivers/mhvtl/major
- Remove external script to create device nodes. Each daemon creates its own
  device node at startup. Uses 'kernel module' major no. sys interface.
- Fix potential NULL pointer usage in REQUEST SENSE
- VPD page 0x83 NAA field fix
- VPD page length fix (only 0x50 bytes in size not 0x52)
- Hopefully removed last reference to /proc
- Use setuidgid if availble instead of 'su $USER -c <vtltape|vtllibrary>'
- Add kernel module RPM spec file for RedHat
- Add Gentoo build

* Wed Sep 01 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.10
- Correct incorrect usage of & vs &&
- Fix TapeAlert.
  Error where the flags were not being set due to an earlier change.
- Add extra verbage around positioning information. Trying to track down
  a problem with HP Dataprotector when it spaces back a block.
- Make tape media & drive type loading logs more readable.
- New utility 'tapeexerciser' which I've been using to track down the
  Dataprotector issue. A simple & basic 'st ioctl()' test utility.
- Fix 'is vtl running' logic in rc script. Was broken if USER == root

* Wed Jul 09 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.9
- Fix WORM media support - Bug report from Albert Pauw
- Complete LTO5 media support

* Wed Jun 23 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.8
- Several Security Protocol IN updates - thanks Albert Pauw
  * Return certificate data
  * Correct length for 'KEY FORMATS'
  * Correct length for SPIN SUPPORTED PAGES
- Fix kernel compile on RedHat AS4
- Media/drive matching now 'dynamic' and defined in device.conf
- Added man page for device.conf
- Fix media corruption when media is 'formatted'
- Add LTO5 & SDLT-S4 drive/media types
- Handle INQUIRY correctly after media change (return SAM_STAT_GOOD)
- Updated rc script so all devices created on Target & LUN. i.e. Don't use
  channel. Some application software has trouble if only the channel is unique.

* Sat May 08 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.7
- Allow media sizes larger than 2G on 32bit platforms
- Implement STK vendor unique op code 'LOAD DISPLAY' -> logs via syslog.
- Fix core dump on invalid data in NAA strings.
- Support VENDOR ID for SMC device with embedded spaces

* Thu May 02 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.6
- Support VENDOR ID with embedded spaces
- Fix 'vtlcmd list map'
- Fix import of media via MAP (off-by-one)
- Return TapeCapacity LOG SENSE in bytes/KB/MB depending on drive type
- Honour MAP status (return error if MAP is open and robot attempts to
  move media in/out of MAP)
- General cleanup of kernel module (thanks to Herbert Stadler)
- Relax dependencies on /proc in faviour of /sys

* Thu Apr 01 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.5
- Silence warning regarding local_irq_save() - Thanks to Norm Lunda
- Re-work param parsing used by vtlcmd - Thanks to Herbert Stadler
- Fix homepage URL

* Fri Mar 05 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.4
- Fix syntax in rc script. Reported by Nabil
  That's what I get for rushing a fix out (ELEMENT STATUS) without testing
  everything..

* Thu Mar 04 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.3
- Test media mounted before REWIND (TSM seems to ignore previous TUR)
- Make creation of media home dir more robust
- Add queue depth callback - Defaults to 32.
- Conversion script of old config files to new format
- Fix problem with size of ELEMENT STATUS DATA length. Thanks to Norm Lunde.

* Thu Jan 28 2010 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.2
- Add support for multiple libraries on single host
- pack MAM struct so it's 1024 bytes on both 32 & 64bit hosts
- Updated URL after google moved it

* Wed Dec 16 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.11
- Add tests for media/drive type. i.e. Only allow LTO media in LTO drives.
- New defination for 'Compression:' in device.conf (Thanks Kevan Rehm)
  ' Compression: factor [1-9] enabled [0|1]'
        Where factor : 1 Fastest compression -> 9 Best compression
             enabled : 0 => Compression disabled, 1 => Compression enabled

* Tue Dec 15 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.1
- Fix data silent data corruption.
- Add tests for media/drive type. i.e. Only allow LTO media in LTO drives.
- Increased max number of LUNs from 7 to 32
- Changed ' Compression: factor X enabled Y' to same as 0.16 branch.
  ' Compression: factor [1-9] enabled [0|1]'
        Where factor : 1 Fastest compression -> 9 Best compression
             enabled : 0 => Compression disabled, 1 => Compression enabled

* Tue Dec 01 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.18.0
- Kevan Rehm reworked media format. The 'old' format suffered from performance
  problems. The larger the defined tape capacity, the longer it took to
  seek/position due to the sequential walk of header structures.

  The new tape format consists of three files.
   .data - Data file.
   .indx - Arrary of one header structure per written tape block or filemark.
   .meta - MAM, followed by meta header structure, followed by variable length
           of filemark block numbers
   Each Physical Cartridge Label (PCL) is located under its own directory
   MHVTL_HOME_PATH/<PCL>/

* Sun Nov 29 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.9
- Check string length in device.conf and abort if too long.
- Compression now working.
  Set up via MODE SELECT op code.
  Set default compression in device.conf 'Compression: X'
   Where 0 is off, 9 is max.
- Defaults with SPECTRA/PYTHON library
- Fix kernel module compile on 2.6.31+ (Ubuntu 9.10)
- Fix kernel silent data corruption
- Set kernel ENABLE_CLUSTERING to enable > 512k blocks on x86_64
- SPIN/SPOUT: Return correct list of supported pages.

* Tue Nov 10 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.8
- Reworked READ ELEMENT STATUS (Thanks to Kevan Rehm)
- Fix EOD header size.
- Makefile rework.
  Honour PREFIX & DESTDIR.
  User/group name defined.
  Home paths for data files & config files defined.
  Add compression support (disabled by default).

* Thu Oct 9 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.7
  Fix REPORT ELMEMENT STATUS for All elements. TSM was core dumping.
  Reported and fixed by Bernardo Clavijo.
  Re-worked Media Access Port.
   Now requires 'vtlcmd library open map' before media can be removed and
   'vtlcmd library close map' for the Medium Transport Element to place
   media into the MAP.

* Thu Oct 1 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.6
  Fixed output of 'dump_tape' utility

* Wed Sep 16 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.5
  Fixed verbosity test in MHVTL_DBG macro (again)

* Tue Sep 15 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.4
  More logging cleanups
  Fixed verbosity test in MHVTL_DBG macro

* Wed Sep 02 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.3
  Reworked logging using a macros MHVTL_DBG.
  Increased max block size to kernel max (from 256k)

* Sat Aug 15 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.2
  Changed/updated load MAP() functionality.
  Previous implementation re-read config file and parsed the MAP slots.
  This is 'interactive' using the vtlcmd command.
   e.g. vtlcmd library load map BARCODE
  Corrected NAA field in VPD page 0x83. This was a hard coded string.
   Now reads entry from /etc/mhvtl/device.conf
	' NAA: 11:22:33:44:ab:cd:ef:03' (8 octet value)
  Remove dependency on sg3_utils

* Wed Aug 05 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.1
  Fixed kernel module oops on lu removal - Many thanks to Jean-Francois
  Added loadMap() to vtllibrary.

* Tue Jul 09 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.16.0
- Moved INQUIRY into userspace.
  Re-jigged all helper scripts.
  Still need to do dynamic config of : vpd pages & mode pages.
- Added pseudo encryption support (SPIN/SPOUT op codes)
- kernel module will oops if unloaded and re-loaded..

* Fri Jan 02 2009 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.10
- Removed kfifo from data path for SCSI OP codes which originate at the target
- Add simple SCSI Persistent Reserve
- Major change to kernel module. Replaced queued_command_arr[] with linked list

* Thu Nov 27 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.9
- Re-fixed WRITE ATTRIBUTE bug forcing a rewind of media.
- Fixed build for PPC64 platform
- Add special reserved barcode 'NOBAR' to indicate a slot is full but
  contains no barcode.

* Fri Nov 21 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.8
- Added initial SECURITY PROTOCOL code

* Tue Nov 19 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.7
- Merge READ ATTRIBUTES fixes from Raymond Gilson

* Sun Nov 16 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.6
- Fixed bug where WRITE ATTRIBUTE was causing media to rewind.
- Increase default buffer size of SMC from 512k to 1024k - Ability to handle
  more (twice the) slots

* Fri Nov 14 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.5
- sg structure changed between 2.6.23 and 2.6.24 causing the kernel module
  to no longer build on latest kernel.

* Fri Apr 04 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.4
- Kernel module change. Default type is SDLT600 instead of IBM TD3 as there is
  confusion on the windows side of things regarding IBM Drivers vs IBM for
  Tivoli vs Symantec Tape Drivers.
  Maybe the QUANTUM SDLT600 will behave better ??
  Only time will tell...

* Fri Mar 28 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.3
- Return 'block descriptor data' on a MODE SENSE 'page 0' instead of an error.

* Mon Mar 10 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.2
  Re-org of the source code.
  - Placed user-space code in directory ./usr
  - Moved kernel drivers from ./kernel-driver/linux-2.6 to ./kernel
  Yet another 'tunable' option. Set the firmware release to "string" by
  # echo "5400" > /sys/bus/pseudo/drivers/vtl/firmware

* Thu Mar 06 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.15.1
  Ability to define default media size in /etc/vtl/vtl.conf

* Wed Mar 05 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Name change as 'vtl' is was deemed too generic.
  Renamed to 'mhvtl' as this is being used by Symantec's Roseville office and
  is as good a name as any.
- With the new name comes a new version 0.15.0

* Tue Feb 19 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.14.1
  Cleaned up compile time warnings on x86_64 platform.
  Added sg_utils and zlib as RPM 'requires' packages.

* Thu Feb 14 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.14.0
- With the ability to define device serial numbers, I thought it was time
  to increase vers from 0.12 to 0.14
- Cleaned up helper scripts.

* Fri Feb 08 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12.37
- Added ability to set serial number via new utility 'vtl_set_sn -q X'
  The serial number is read from /etc/vtl/library_config for each 'Drive X:'
  e.g.
   Drive 2: SN20034
   Drive 3: SN20035
  If there is no serial number defined in library_config file, and the
  serial prefix has been set, then this will be used. Otherwise the old &
  trusted method of calculating based on HBA#, ID# & LUN.

* Wed Feb 06 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12.36
- Added another config file /etc/vtl/vtl.conf
- Added ability to set a serial number prefix for devices.
- Added ability to set the buffer size used by SSC devices.
- Added ability to set/clear logging levels within vtl.conf

* Sat Feb 02 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-35
- Fix post uninstall
  check for group & passwd entries before attempting to run groupdel/userdel

* Sat Jan 08 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-34
  Changes to kernel module & rc scripts.
- Default kernel module load reporting the library only.
- The rc scripts now update the number of required tape devices depending on
  the contents of /etc/vtl/library_contents
- Using the max_luns or num_tgts the library can consist of different drives
  or all the same drive type.
- Deleted x86_64 patch as it is no longer needed.

* Fri Jan 04 2008 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Reserved vers 0.12-33
  A special build with only 5 IBM drives.

* Wed Dec 19 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-32
- Changed user 'vtl' home directory to /opt/vtl
  Otherwise there can be problems starting the vtl s/w if /home is an
  automount and can't mount /home.
- Changed kernel module Makefile
  To compile on Debian or Ubuntu systems "make ubuntu=1"
  To compile on SuSE or RedHat systems "make"

* Tue Oct 16 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-31
- No code changes. As sysdup has crashed and management have decided not to
  replaced the two failed drives in the RAID 5 system, I've changed the
  home of this project to my google homepage.

* Tue Oct 16 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-30
- vtl kernel module: - bumped to 0.12.14 20071015-0
- Another bug fix in the kernel module. This time copying data from user-space
  in an unsafe manner. Last reason for kernel oops ??
- Make library module startup more robust by clearing out message Q at start
  time.
- Set vtl startup to 'on' at package install time.

* Wed Oct 10 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-28
- vtl kernel module: - bumped to 0.12.14 20071010-0
- Many updates to error handling condition.

* Wed Sep 26 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-26
- vtl kernel module: - bumped to 0.12.14 20070926-0
  Moved memory alloc from devInfoReg() to vtl_slave_alloc() - I now don't get
  those horrible "Debug: sleeping function called from invalid context"

* Tue Sep 25 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-25
- Resolved an issue where virtual media was being corrupted when performing
  erase operation.

* Sat Sep 22 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-24
- On corrupt media load, return NOT READY/MEDIUM FORMAT CORRUPT

* Fri Sep 21 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-23
- vtl kernel module bug fix - resolved a race condition with my usage of
  copy_to_user()/copy_from_user() and c_ioctl() routines.
  Thanks to Ray Schafer for finding and being able to reproduce race.

* Fri Aug 24 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-22
- Set correct directory ownership and permissions at post install time
  for /opt/vtl

* Wed Aug 01 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-21
- Corrected warnings identified by sparse

* Sat Apr 07 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-20
- Calls to tune kernel behaviour of out-of-memory always return 'success'.
  Found out the hard way, earlier kernel versions do not support this feature.
- Added check for return status from build_library_config in rc script

* Sat Mar 31 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-19
- Added conditional x86_64/amd64 to vtl.spec so it builds correctly on x86_64
  platforms.

* Wed Mar 28 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-18
- Improved (slightly) checking of MAM header on media open.
  At least made it 32/64 bit friendly.

* Thu Mar 24 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-17
- Added 'Out Of Memory killer tuning to both vtltape and vtllibrary.
- Added 'tags' as a target in Makefile, i.e. 'make tags'
  TAGS will be removed with a 'make distclean'

* Thu Mar 13 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-16
- Added -D_LARGEFILE64 switch to Makefile to allow a more portable way of
  opening files > 2G. There should be no need for the x86_64 patch any more.
  Needs testing.

* Thu Feb 22 2007 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-14
- Added 'ERASE(6)' command as a result of bug report from Laurent Dongradi.
  NetBackup "bplabel -erase -l " command failing.

* Thu Sep 07 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-13
- Just updated some time/date in kernel module. Nothing major.

* Tue Sep 05 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-12
  Shared library (libvxscsi.so) conflict with Symantec VRTSvxvm-common-4.1.20
  so I've renamed mine to libvtlscsi.so
  Should build correctly on an x86_64 RPM system now.

* Thu Aug 31 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-10 (skipped numbering between -5 & -10
  Changed interface between user-space and kernel, hence need kernel module
  version 0.12.10
  The change is to support 'auto sense', where the sense buffer is sent straight
  after the data (if sense data is valid).
  Need to fix: Way of specifying size of sense buffer. Currently defined in
  kernel src (vtl.c) and user-space header vx.h. It would be nice to have this
  defined in one place only.
- Updated rc script to check kernel version before starting user-space daemons.

* Wed Jul 05 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-5
- Updated man pages to reflect name changes from vxtape/vxlibrary to
  vtltape/vtllibrary
- Removed any vxtape/vxlibrary binaries from build process

* Tue Jul 04 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-4
- Fixed (Well tested) kernel makefile compile on SLES 9 and suse 9.3
  i.e. Kernel versions 2.6.5-7.191-smp & 2.6.11.4-21.12-smp
  Hacked scsi.h include file and added #if KERNEL_VERSION conditional compile
  around kfifo.[ch] if below 2.6.10
- Attempt to improve install/startup on RedHat AS4 + SLES9

* Sun Jul 02 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.12-0
- Forked this version from main tree. Main branch is 0.13.x which will continue
  to be work-in-progress for removal of kfifo routines.
- 0.12-x is to be current 'stable' branch.

* Fri May 19 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.10-13
- Added TapeUsage & TapeCapacity log parameters. Even thou I'm specifying these
  pages are not supported, BackupExec still probes for them and barfs on the
  scsi error returned.

* Thu May 18 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.10-12
- Re-worked the READ ELEMENT STATUS command with the idea of adding the extra
  options which appear to be required by BackupExec.

* Wed May 10 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped vers to 0.10-10
- Fixed bug introduced in vtllibrary where I broke the inventory function.

* Tue May 09 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Changed poll of 'getting SCSI command' to use ioctl instead of kfifo.
  Requires kernel module dated > 20060503-0

* Sun Apr 30 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Fixed typo in rc script where trying to set permissions on /dev/vx? instead
  of /dev/vtl?

* Sat Apr 29 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Changed logic on WIRTE-FILEMARK SCSI command. Now only attempts to write
  filemarks if greater the 0 filemarks specified.
- Added check for SuSE-release and use '{user|group}add --system' switch
  otherwise {user|group}add without the --system switch.
- Bumped version to 0.10-6

* Thu Apr 27 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Seek to EndOfData bug where the tape daemon would loop over the last block
  and never return.

* Sat Apr  5 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Changed the kernel module from 'vx_tape' to vtl (no real impact to user space
- daemons) however changing /dev/ entries from /dev/vx? to /dev/vtl due to name
- space clash with VERITAS StorageFoundation (VxVM/VxFS)

* Sat Apr  1 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Bumped version to 0.9 as this has the start of a working Solaris port.

* Thu Mar 24 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Added extra logging for mode_sense command if verbose > 2

* Thu Mar 10 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Start of Solaris kernel port.
- Moved kernel driver into seperate subdir.
- Added some 'ifdef Solaris' to source code.

* Thu Feb 22 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Added check to make sure RPM_BUILD_ROOT is not / when attempting to remove.
- Shutdown daemons before package removal

* Thu Feb 16 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Added ALLOW/DENY MEDIUM REMOVAL SCSI cmd to vxlibrary daemon.
- Added Extend/Retract checking to MOVE MEDIUM SCSI cmds.

* Thu Feb 14 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Made RPM create system account of 'vtl' & group of 'vtl' before install.

* Thu Feb 11 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- bump vers from 0.7 to 0.8
- Rename /opt/vx_media to /opt/vtl
- Rename /etc/vxlibrary to /etc/vtl
- RPM install now creates vtl user & group
- rc script now installs a default library config file in /etc/vtl/

* Thu Feb  2 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Teach me for not testing fully. Resolved bug where no data was written.

* Thu Feb  2 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Improvements to handling of cleaning media.

* Wed Jan  3 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Added a new man page vtl, which aims to document how this package hangs
  together.
- Corrected a couple of hard-coded paths in rc scripts

* Wed Jan  3 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Moved source man pages into separate man directory.
- Updated version of user-mode utilities to that of the kernel module (v0.7)

* Tue Jan  3 2006 Mark Harvey <markh794@gmail.com> <mark_harvey@symantec.com>
- Added man pages.



================================================
FILE: INSTALL
================================================
mh virtual tape & library system.


Instructions assume reader is familiar with the kernel build process.

There are two sections of code to build.
- The kernel module
- The user-space daemons.

Kernel module mhvtl:
==================
1) Make sure the kernel-devel package to match your running kernel is installed.
e.g.
RedHat AS 4 & 5:

	sh> rpm -qa|grep kernel
	kernel-2.6.9-34.0.1.EL
	kernel-devel-2.6.9-34.0.1.EL
	kernel-2.6.9-5.EL
	kernel-devel-2.6.9-5.EL
	kernel-utils-2.4-13.1.80

SLES 9 & 10:

	sh> rpm -qa|grep kernel


2) Extract the mhvtl source code.

	sh> tar xvfz mhvtl-2012-06-15.tgz

3) Change directory into the kernel driver source.

	sh> cd mhvtl-1.3/kernel/
	sh> make
	sh> sudo make install


User space daemons:
===================
Pre-req for a running mhvtl
- sg3_utils (http://sg.danny.cz/sg/sg3_utils.html)

Pre-req to build/compile userspace:
- zlib-devel
- lzo-devel

* To build an RPM
  ===============

	sh> sudo cp mhvtl-YYYY-MM-DD.tar.gz /usr/src/packages/SOURCE/
	sh> cd /usr/src/packages/SOURCE
	sh> sudo rpmbuild -tb mhvtl-YYYY-MM-DD.tar.gz
	...  <wait for rpm build to complete>
	sh> sudo rpm -Uvh /usr/src/packages/RPMS/<cpu type>/mhvtl-1.3-z.<cpu type>.rpm
	...

- Note: For RedHat, replace 'packages' with 'redhat'

* To build from tar archive (Debian / Ubuntu):
  ============================================
 apt-get install lsscsi
 apt-get install sg3-utils

Note: we used to create a user and group called "vtl" to try to limit
the possible system hazards of having root access. But we now feel
that normal Linux permissions and security controls are sufficient.

Also note: The package sg3-utils has a different name based on the distribution
used. Most distributions (Red Hat/Suse/Centos) use an underscore (sg3_utils).
Debian based distributions (Debian/Ubuntu/Mint use a hyphen (sg3-utils).

Now build user space daemons:
From the parent directory where you extracted the source.

	sh> cd mhvtl-1.3

Build the binaries

	sh> make

Install the systemd scripts and binaries and tell systemd:

	sh> sudo make install
	sh> sudo systemctl daemon-reload

Enable and start the mhvtl target service:

	sh> sudo systemctl enable mhvtl.target
	sh> sudo systemctl start mhvtl.target

And make sure it worked:

	sh> sudo systemctl status mhvtl.target

You can test that your vtl* daemons are running with:

	sh> ps -ax | fgrep vtl

Test:
Note: Make sure the 'mtx' & 'lsscsi' utilities are installed
The virtual devices are attached to HBA #5 in this example.
e.g.
# lsscsi -g
[0:0:0:0]    disk    ATA      WDC WD1200BEVS-0 02.0  /dev/sda  /dev/sg0
[3:0:0:0]    cd/dvd  Optiarc  DVD RW AD-7910A  1.D1  /dev/sr0  /dev/sg1
[5:0:0:0]    mediumx SPECTRA  PYTHON           5500  /dev/sch0  /dev/sg6
[5:0:1:0]    tape    QUANTUM  SDLT600          5500  /dev/st0  /dev/sg2
[5:0:2:0]    tape    QUANTUM  SDLT600          5500  /dev/st1  /dev/sg3
[5:0:3:0]    tape    IBM      ULT3580-TD4      5500  /dev/st2  /dev/sg4
[5:0:4:0]    tape    IBM      ULT3580-TD4      5500  /dev/st3  /dev/sg5


# mtx -f /dev/sg6 status
  Storage Changer /dev/sg6:4 Drives, 37 Slots ( 4 Import/Export )
Data Transfer Element 0:Empty
Data Transfer Element 1:Empty
Data Transfer Element 2:Empty
Data Transfer Element 3:Empty
      Storage Element 1:Full :VolumeTag=SDLT01S3
      Storage Element 2:Full :VolumeTag=SDLT02S3
      Storage Element 3:Full :VolumeTag=SDLT03S3
      Storage Element 4:Full :VolumeTag=SDLT04S3
      Storage Element 5:Full :VolumeTag=SDLT05S3
      Storage Element 6:Full :VolumeTag=SDLT06S3
      Storage Element 7:Full :VolumeTag=SDLT07S3
      Storage Element 8:Full :VolumeTag=SDLT08S3
      Storage Element 9:Full :VolumeTag=SDLT09S3
      Storage Element 10:Empty
      Storage Element 11:Full :VolumeTag=ULT001L1
      Storage Element 12:Full :VolumeTag=ULT002L2
      Storage Element 13:Full :VolumeTag=ULT003L3
      Storage Element 14:Full :VolumeTag=ULT004L4
      Storage Element 15:Full :VolumeTag=ULT005L1
      Storage Element 16:Full :VolumeTag=ULT006L2
      Storage Element 17:Full :VolumeTag=ULT007L3
      Storage Element 18:Full :VolumeTag=ULT008L4
      Storage Element 19:Full :VolumeTag=ULT009L1
      Storage Element 20:Empty
      Storage Element 21:Full :VolumeTag=8MM001X4
      Storage Element 22:Full :VolumeTag=8MM002X4
      Storage Element 23:Full :VolumeTag=8MM003X4
      Storage Element 24:Full :VolumeTag=8MM004X4
      Storage Element 25:Empty
      Storage Element 26:Empty
      Storage Element 27:Empty
      Storage Element 28:Empty
      Storage Element 29:Empty
      Storage Element 30:Empty
      Storage Element 31:Full :VolumeTag=CLN001L1
      Storage Element 32:Full :VolumeTag=CLN002L1
      Storage Element 33:Full :VolumeTag=CLN003L1
      Storage Element 34 IMPORT/EXPORT:Empty
      Storage Element 35 IMPORT/EXPORT:Empty
      Storage Element 36 IMPORT/EXPORT:Empty
      Storage Element 37 IMPORT/EXPORT:Empty


Enjoy.

Please feel free in letting me know if this works for you.

Bug fixes and suggestions always welcome.

markh794@gmail.com


================================================
FILE: Makefile
================================================
#
# This makefile needs to be invoked as follows:
#
#make <options>
#
# Here, options include:
#
# 	all 	to build all utilities
# 	clean	to clean up all intermediate files
# 	kernel	to build kernel module
#

include config.mk

PARENTDIR = mhvtl-$(VER)
CHECK_CC = cgcc
CHECK_CC_FLAGS = '$(CHECK_CC) -Wbitwise -Wno-return-void -no-compile $(ARCH)'

TAR_FILE := mhvtl-$(shell date +%F)-$(VERSION).$(EXTRAVERSION).tgz

MAKE_VTL_MEDIA = usr/bin/make_vtl_media

export PREFIX DESTDIR TOPDIR

CFLAGS=-Wall -g -O2 -D_LARGEFILE64_SOURCE $(RPM_OPT_FLAGS)
CLFLAGS=-shared

all:	usr etc scripts

scripts:	patch
	$(MAKE) -C scripts

etc:	patch
	$(MAKE) -C etc

usr:	patch
	$(MAKE) -C usr

kernel: patch
	$(MAKE) -C kernel

.PHONY:check
check:	ARCH=$(shell sh scripts/checkarch.sh)
check:
	CC=$(CHECK_CC_FLAGS) $(MAKE) all


patch:


install: all
	[ -d $(DESTDIR)$(MHVTL_HOME_PATH) ] || mkdir -p $(DESTDIR)$(MHVTL_HOME_PATH)
	$(MAKE) -C usr install
	$(MAKE) -C scripts install
	$(MAKE) -i -C etc install
	$(MAKE) -C man install
	$(MAKE) -C kernel install
ifeq ($(ROOTUID),YES)
	systemctl daemon-reload
endif

tape: # now ensure VTL media is setup
	env LD_LIBRARY_PATH=$(DESTDIR)$(LIBDIR) \
		$(MAKE_VTL_MEDIA) \
			--config-dir=$(DESTDIR)$(MHVTL_CONFIG_PATH) \
			--home-dir=$(DESTDIR)$(MHVTL_HOME_PATH) \
			--mktape-path=usr/bin

.PHONY:uninstall
uninstall:
	$(MAKE) -C usr uninstall
	$(MAKE) -C scripts uninstall
	$(MAKE) -i -C etc uninstall
	$(MAKE) -C man uninstall
	$(MAKE) -C kernel uninstall
ifeq ($(ROOTUID),YES)
	systemctl daemon-reload
endif

tar: distclean
	test -d ../$(PARENTDIR) || ln -s $(TOPDIR) ../$(PARENTDIR)
	(cd kernel; tar --transform='s|.*/||' \
		-cfz ../mhvtl_kernel.tgz * ../include/common/*)
	(cd ..;  tar cvzf $(TAR_FILE) --exclude='.git*' \
		 $(PARENTDIR)/man \
		 $(PARENTDIR)/doc \
		 $(PARENTDIR)/kernel \
		 $(PARENTDIR)/usr \
		 $(PARENTDIR)/etc/ \
		 $(PARENTDIR)/scripts/ \
		 $(PARENTDIR)/ccan/ \
		 $(PARENTDIR)/tcopy/ \
		 $(PARENTDIR)/include \
		 $(PARENTDIR)/Makefile \
		 $(PARENTDIR)/config.mk \
		 $(PARENTDIR)/README \
		 $(PARENTDIR)/INSTALL \
		 $(PARENTDIR)/ChangeLog \
		 $(PARENTDIR)/mhvtl_kernel.tgz \
		 $(PARENTDIR)/mhvtl-utils.spec)
	$(RM) ../$(PARENTDIR)

.PHONY:tags
tags:
	$(MAKE) -C usr tags
	$(MAKE) -C kernel tags

# ========== Cleaning ==========

.PHONY:clean
clean:
	$(MAKE) -C usr clean
	$(MAKE) -C etc clean
	$(MAKE) -C scripts clean
	$(MAKE) -C man clean
	$(MAKE) -C kernel clean
	$(RM) mhvtl_kernel.tgz

.PHONY: distclean
distclean:
	$(MAKE) -C usr distclean
	$(MAKE) -C etc distclean
	$(MAKE) -C scripts distclean
	$(MAKE) -C kernel distclean
	$(MAKE) -C man distclean
	$(RM) mhvtl_kernel.tgz
	$(RM) ../$(TAR_FILE)


================================================
FILE: README
================================================

mhvtl: A Virtual Tape & Library system.

This package is composed of a kernel module (mhvtl) which is a pseudo HBA

The vtl is basically a stripped down scsi_debug kernel module + a char dev
'back end' to pass the SCSI commands thru to user space daemons. It is the
user space daemons responsibility to respond and process the SCSI commands.

See the INSTALL file for compile and install instructions.

This has been my first attempt at kernel level programming. Suggestions and
comments always welcome. It has also been many years since I have done any c
programming. Please be gentle..

Mark Harvey
markh794@gmail.com


================================================
FILE: ccan/ccan/crc32c/_info
================================================
#include "config.h"
#include <string.h>
#include <stdio.h>

/**
 * crc32c - routine for Castagnoli CRC (crc32c) of bytes
 *
 * Cyclic Redundancy Check routine, optimized for x86-64.  Reasonably fast
 * checksum routines, but not suitable for cryptographic use.
 *
 * They are useful for simple error detection, eg. a 32-bit CRC will
 * detect a single error burst of up to 32 bits.
 *
 * Example:
 *	#include <ccan/crc32c/crc32c.h>
 *	#include <stdio.h>
 *	#include <stdlib.h>
 *
 *	// Given "123456789" outputs 0xe3069283
 *	int main(int argc, char *argv[])
 *	{
 *		if (argc != 2) {
 *			fprintf(stderr, "Usage: %s <string>\n"
 *				"Prints 32 bit CRC of the string\n", argv[0]);
 *			exit(1);
 *		}
 *		printf("0x%08x\n", crc32c(0, argv[1], strlen(argv[1])));
 *		exit(0);
 *	}
 *
 * License: MIT
 * Author: Mark Adler
 * Maintainer: Rusty Russell <rusty@rustcorp.com.au>
 */
int main(int argc, char *argv[])
{
	if (argc != 2)
		return 1;

	if (strcmp(argv[1], "depends") == 0) {
		printf("ccan/compiler\n");
		return 0;
	}

	return 1;
}


================================================
FILE: ccan/ccan/crc32c/benchmark/Makefile
================================================
CCANDIR=../../..
CFLAGS=-Wall -Werror -O3 -I$(CCANDIR) -flto
#CFLAGS=-Wall -Werror -g3 -I$(CCANDIR)
LDFLAGS := -flto -O3

all: bench

CCAN_OBJS:=ccan-tal.o ccan-tal-grab_file.o ccan-noerr.o ccan-take.o ccan-time.o

bench: bench.o $(CCAN_OBJS)

clean:
	rm -f bench *.o

ccan-time.o: $(CCANDIR)/ccan/time/time.c
	$(CC) $(CFLAGS) -c -o $@ $<
ccan-tal.o: $(CCANDIR)/ccan/tal/tal.c
	$(CC) $(CFLAGS) -c -o $@ $<
ccan-take.o: $(CCANDIR)/ccan/take/take.c
	$(CC) $(CFLAGS) -c -o $@ $<
ccan-noerr.o: $(CCANDIR)/ccan/noerr/noerr.c
	$(CC) $(CFLAGS) -c -o $@ $<
ccan-tal-grab_file.o: $(CCANDIR)/ccan/tal/grab_file/grab_file.c
	$(CC) $(CFLAGS) -c -o $@ $<


================================================
FILE: ccan/ccan/crc32c/benchmark/bench.c
================================================
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/tal.h>
#include <ccan/time/time.h>
#include <ccan/crc32c/crc32c.c>
#include <assert.h>
#include <ccan/err/err.h>

#define RUNS 65536

int main(int argc, char *argv[])
{
	void *p;
	struct timeabs start, end;
	size_t len, runs;
	uint64_t sums = 0;
	bool sw = false, hw = false;

	if (argv[1]) {
		if (streq(argv[1], "--software")) {
			sw = true;
			argv++;
			argc--;

		} else if (streq(argv[1], "--hardware")) {
			hw = true;
			argv++;
			argc--;
		}
	}

	if (argc < 2 || (runs = atol(argv[1])) == 0)
		errx(1, "Usage: bench <num-runs> [<file>]");

	p = grab_file(NULL, argv[2]);
	if (!p)
		err(1, "Reading %s", argv[2] ? argv[2] : "<stdin>");
	len = tal_count(p) - 1;
	start = time_now();
	if (sw) {
		for (size_t i = 0; i < runs; i++)
			sums += crc32c_sw(0, p, len);
	} else if (hw) {
		for (size_t i = 0; i < runs; i++)
			sums += crc32c_hw(0, p, len);
	} else {
		for (size_t i = 0; i < runs; i++)
			sums += crc32c(0, p, len);
	}
	end = time_now();

	assert(sums % runs == 0);
	printf("%u usec for %zu bytes, sum=%08x\n",
	       (int)time_to_usec(time_divide(time_between(end, start), runs)),
	       len,
	       (unsigned int)(sums / runs));
	return 0;
}


================================================
FILE: ccan/ccan/crc32c/crc32c.c
================================================
/* MIT (BSD) license - see LICENSE file for details */
/* crc32c.c -- compute CRC-32C using the Intel crc32 instruction
 * Copyright (C) 2013, 2015 Mark Adler
 * Version 1.3  31 Dec 2015  Mark Adler
 */

/*
  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the author be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Mark Adler
  madler@alumni.caltech.edu
 */

/* Use hardware CRC instruction on Intel SSE 4.2 processors.  This computes a
   CRC-32C, *not* the CRC-32 used by Ethernet and zip, gzip, etc.  A software
   version is provided as a fall-back, as well as for speed comparisons. */

/* Version history:
   1.0  10 Feb 2013  First version
   1.1   1 Aug 2013  Correct comments on why three crc instructions in parallel
   1.2   1 Nov 2015  Add const qualifier to avoid compiler warning
                     Load entire input into memory (test code)
                     Argument gives number of times to repeat (test code)
                     Argument < 0 forces software implementation (test code)
   1.3  31 Dec 2015  Check for Intel architecture using compiler macro
                     Support big-endian processors in software calculation
                     Add header for external use
 */

#include "crc32c.h"
#include <ccan/compiler/compiler.h>
#include <stdbool.h>

static uint32_t crc32c_sw(uint32_t crc, void const *buf, size_t len);

/* CRC-32C (iSCSI) polynomial in reversed bit order. */
#define POLY 0x82f63b78

#ifdef __x86_64__

/* Hardware CRC-32C for Intel and compatible processors. */

/* Multiply a matrix times a vector over the Galois field of two elements,
   GF(2).  Each element is a bit in an unsigned integer.  mat must have at
   least as many entries as the power of two for most significant one bit in
   vec. */
static inline uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec) {
    uint32_t sum = 0;
    while (vec) {
        if (vec & 1)
            sum ^= *mat;
        vec >>= 1;
        mat++;
    }
    return sum;
}

/* Multiply a matrix by itself over GF(2).  Both mat and square must have 32
   rows. */
static inline void gf2_matrix_square(uint32_t *square, uint32_t *mat) {
    for (unsigned n = 0; n < 32; n++)
        square[n] = gf2_matrix_times(mat, mat[n]);
}

/* Construct an operator to apply len zeros to a crc.  len must be a power of
   two.  If len is not a power of two, then the result is the same as for the
   largest power of two less than len.  The result for len == 0 is the same as
   for len == 1.  A version of this routine could be easily written for any
   len, but that is not needed for this application. */
static void crc32c_zeros_op(uint32_t *even, size_t len) {
    uint32_t odd[32];       /* odd-power-of-two zeros operator */

    /* put operator for one zero bit in odd */
    odd[0] = POLY;              /* CRC-32C polynomial */
    uint32_t row = 1;
    for (unsigned n = 1; n < 32; n++) {
        odd[n] = row;
        row <<= 1;
    }

    /* put operator for two zero bits in even */
    gf2_matrix_square(even, odd);

    /* put operator for four zero bits in odd */
    gf2_matrix_square(odd, even);

    /* first square will put the operator for one zero byte (eight zero bits),
       in even -- next square puts operator for two zero bytes in odd, and so
       on, until len has been rotated down to zero */
    do {
        gf2_matrix_square(even, odd);
        len >>= 1;
        if (len == 0)
            return;
        gf2_matrix_square(odd, even);
        len >>= 1;
    } while (len);

    /* answer ended up in odd -- copy to even */
    for (unsigned n = 0; n < 32; n++)
        even[n] = odd[n];
}

/* Take a length and build four lookup tables for applying the zeros operator
   for that length, byte-by-byte on the operand. */
static void crc32c_zeros(uint32_t zeros[][256], size_t len) {
    uint32_t op[32];

    crc32c_zeros_op(op, len);
    for (unsigned n = 0; n < 256; n++) {
        zeros[0][n] = gf2_matrix_times(op, n);
        zeros[1][n] = gf2_matrix_times(op, n << 8);
        zeros[2][n] = gf2_matrix_times(op, n << 16);
        zeros[3][n] = gf2_matrix_times(op, n << 24);
    }
}

/* Apply the zeros operator table to crc. */
static inline uint32_t crc32c_shift(uint32_t zeros[][256], uint32_t crc) {
    return zeros[0][crc & 0xff] ^ zeros[1][(crc >> 8) & 0xff] ^
           zeros[2][(crc >> 16) & 0xff] ^ zeros[3][crc >> 24];
}

/* Block sizes for three-way parallel crc computation.  LONG and SHORT must
   both be powers of two.  The associated string constants must be set
   accordingly, for use in constructing the assembler instructions. */
#define LONG 8192
#define LONGx1 "8192"
#define LONGx2 "16384"
#define SHORT 256
#define SHORTx1 "256"
#define SHORTx2 "512"

/* Tables for hardware crc that shift a crc by LONG and SHORT zeros. */
static bool crc32c_once_hw;
static uint32_t crc32c_long[4][256];
static uint32_t crc32c_short[4][256];

/* Initialize tables for shifting crcs. */
static void crc32c_init_hw(void) {
    crc32c_once_hw = true;
    crc32c_zeros(crc32c_long, LONG);
    crc32c_zeros(crc32c_short, SHORT);
}

/* Compute CRC-32C using the Intel hardware instruction. */
static uint32_t crc32c_hw(uint32_t crc, void const *buf, size_t len) {
    /* populate shift tables the first time through */
    if (!crc32c_once_hw)
	crc32c_init_hw();

    /* pre-process the crc */
    crc = ~crc;
    uint64_t crc0 = crc;            /* 64-bits for crc32q instruction */

    /* compute the crc for up to seven leading bytes to bring the data pointer
       to an eight-byte boundary */
    unsigned char const *next = buf;
    while (len && ((uintptr_t)next & 7) != 0) {
        __asm__("crc32b\t" "(%1), %0"
                : "=r"(crc0)
                : "r"(next), "0"(crc0));
        next++;
        len--;
    }

    /* compute the crc on sets of LONG*3 bytes, executing three independent crc
       instructions, each on LONG bytes -- this is optimized for the Nehalem,
       Westmere, Sandy Bridge, and Ivy Bridge architectures, which have a
       throughput of one crc per cycle, but a latency of three cycles */
    while (len >= LONG*3) {
        uint64_t crc1 = 0;
        uint64_t crc2 = 0;
        unsigned char const * const end = next + LONG;
        do {
            __asm__("crc32q\t" "(%3), %0\n\t"
                    "crc32q\t" LONGx1 "(%3), %1\n\t"
                    "crc32q\t" LONGx2 "(%3), %2"
                    : "=r"(crc0), "=r"(crc1), "=r"(crc2)
                    : "r"(next), "0"(crc0), "1"(crc1), "2"(crc2));
            next += 8;
        } while (next < end);
        crc0 = crc32c_shift(crc32c_long, crc0) ^ crc1;
        crc0 = crc32c_shift(crc32c_long, crc0) ^ crc2;
        next += LONG*2;
        len -= LONG*3;
    }

    /* do the same thing, but now on SHORT*3 blocks for the remaining data less
       than a LONG*3 block */
    while (len >= SHORT*3) {
        uint64_t crc1 = 0;
        uint64_t crc2 = 0;
        unsigned char const * const end = next + SHORT;
        do {
            __asm__("crc32q\t" "(%3), %0\n\t"
                    "crc32q\t" SHORTx1 "(%3), %1\n\t"
                    "crc32q\t" SHORTx2 "(%3), %2"
                    : "=r"(crc0), "=r"(crc1), "=r"(crc2)
                    : "r"(next), "0"(crc0), "1"(crc1), "2"(crc2));
            next += 8;
        } while (next < end);
        crc0 = crc32c_shift(crc32c_short, crc0) ^ crc1;
        crc0 = crc32c_shift(crc32c_short, crc0) ^ crc2;
        next += SHORT*2;
        len -= SHORT*3;
    }

    /* compute the crc on the remaining eight-byte units less than a SHORT*3
       block */
    {
        unsigned char const * const end = next + (len - (len & 7));
        while (next < end) {
            __asm__("crc32q\t" "(%1), %0"
                    : "=r"(crc0)
                    : "r"(next), "0"(crc0));
            next += 8;
        }
        len &= 7;
    }

    /* compute the crc for up to seven trailing bytes */
    while (len) {
        __asm__("crc32b\t" "(%1), %0"
                : "=r"(crc0)
                : "r"(next), "0"(crc0));
        next++;
        len--;
    }

    /* return a post-processed crc */
    return ~crc0;
}

/* Compute a CRC-32C.  If the crc32 instruction is available, use the hardware
   version.  Otherwise, use the software version. */
uint32_t crc32c(uint32_t crc, void const *buf, size_t len) {

    return cpu_supports("sse4.2") ? crc32c_hw(crc, buf, len) : crc32c_sw(crc, buf, len);
}

#else /* !__x86_64__ */

uint32_t crc32c(uint32_t crc, void const *buf, size_t len) {
    return crc32c_sw(crc, buf, len);
}

#endif

/* Construct table for software CRC-32C little-endian calculation. */
static bool crc32c_once_little;
static uint32_t crc32c_table_little[8][256];
static void crc32c_init_sw_little(void) {
    for (unsigned n = 0; n < 256; n++) {
        uint32_t crc = n;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc32c_table_little[0][n] = crc;
    }
    for (unsigned n = 0; n < 256; n++) {
        uint32_t crc = crc32c_table_little[0][n];
        for (unsigned k = 1; k < 8; k++) {
            crc = crc32c_table_little[0][crc & 0xff] ^ (crc >> 8);
            crc32c_table_little[k][n] = crc;
        }
    }
    crc32c_once_little = true;
}

/* Compute a CRC-32C in software assuming a little-endian architecture,
   constructing the required table if that hasn't already been done. */
static uint32_t crc32c_sw_little(uint32_t crc, void const *buf, size_t len) {
    unsigned char const *next = buf;

    if (!crc32c_once_little)
	crc32c_init_sw_little();
    crc = ~crc;
    while (len && ((uintptr_t)next & 7) != 0) {
        crc = crc32c_table_little[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
        len--;
    }
    if (len >= 8) {
        uint64_t crcw = crc;
        do {
            crcw ^= *(uint64_t const *)next;
            crcw = crc32c_table_little[7][crcw & 0xff] ^
                   crc32c_table_little[6][(crcw >> 8) & 0xff] ^
                   crc32c_table_little[5][(crcw >> 16) & 0xff] ^
                   crc32c_table_little[4][(crcw >> 24) & 0xff] ^
                   crc32c_table_little[3][(crcw >> 32) & 0xff] ^
                   crc32c_table_little[2][(crcw >> 40) & 0xff] ^
                   crc32c_table_little[1][(crcw >> 48) & 0xff] ^
                   crc32c_table_little[0][crcw >> 56];
            next += 8;
            len -= 8;
        } while (len >= 8);
        crc = crcw;
    }
    while (len) {
        crc = crc32c_table_little[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
        len--;
    }
    return ~crc;
}

/* Swap the bytes in a uint64_t.  (Only for big-endian.) */
#if defined(__has_builtin) || (defined(__GNUC__) && \
    (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
#  define swap __builtin_bswap64
#else
static inline uint64_t swap(uint64_t x) {
    x = ((x << 8) & 0xff00ff00ff00ff00) | ((x >> 8) & 0xff00ff00ff00ff);
    x = ((x << 16) & 0xffff0000ffff0000) | ((x >> 16) & 0xffff0000ffff);
    return (x << 32) | (x >> 32);
}
#endif

/* Construct tables for software CRC-32C big-endian calculation. */
static bool crc32c_once_big;
static uint32_t crc32c_table_big_byte[256];
static uint64_t crc32c_table_big[8][256];
static void crc32c_init_sw_big(void) {
    for (unsigned n = 0; n < 256; n++) {
        uint32_t crc = n;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc = crc & 1 ? (crc >> 1) ^ POLY : crc >> 1;
        crc32c_table_big_byte[n] = crc;
    }
    for (unsigned n = 0; n < 256; n++) {
        uint32_t crc = crc32c_table_big_byte[n];
        crc32c_table_big[0][n] = swap(crc);
        for (unsigned k = 1; k < 8; k++) {
            crc = crc32c_table_big_byte[crc & 0xff] ^ (crc >> 8);
            crc32c_table_big[k][n] = swap(crc);
        }
    }
    crc32c_once_big = true;
}

/* Compute a CRC-32C in software assuming a big-endian architecture,
   constructing the required tables if that hasn't already been done. */
static uint32_t crc32c_sw_big(uint32_t crc, void const *buf, size_t len) {
    unsigned char const *next = buf;

    if (!crc32c_once_big)
	crc32c_init_sw_big();
    crc = ~crc;
    while (len && ((uintptr_t)next & 7) != 0) {
        crc = crc32c_table_big_byte[(crc ^ *next++) & 0xff] ^ (crc >> 8);
        len--;
    }
    if (len >= 8) {
        uint64_t crcw = swap(crc);
        do {
            crcw ^= *(uint64_t const *)next;
            crcw = crc32c_table_big[0][crcw & 0xff] ^
                   crc32c_table_big[1][(crcw >> 8) & 0xff] ^
                   crc32c_table_big[2][(crcw >> 16) & 0xff] ^
                   crc32c_table_big[3][(crcw >> 24) & 0xff] ^
                   crc32c_table_big[4][(crcw >> 32) & 0xff] ^
                   crc32c_table_big[5][(crcw >> 40) & 0xff] ^
                   crc32c_table_big[6][(crcw >> 48) & 0xff] ^
                   crc32c_table_big[7][(crcw >> 56)];
            next += 8;
            len -= 8;
        } while (len >= 8);
        crc = swap(crcw);
    }
    while (len) {
        crc = crc32c_table_big_byte[(crc ^ *next++) & 0xff] ^ (crc >> 8);
        len--;
    }
    return ~crc;
}

/* Table-driven software CRC-32C.  This is about 15 times slower than using the
   hardware instructions.  Determine the endianess of the processor and proceed
   accordingly.  Ideally the endianess will be determined at compile time, in
   which case the unused functions and tables for the other endianess will be
   removed by the optimizer.  If not, then the proper routines and tables will
   be used, even if the endianess is changed mid-stream.  (Yes, there are
   processors that permit that -- go figure.) */
static uint32_t crc32c_sw(uint32_t crc, void const *buf, size_t len) {
    static int const little = 1;
    if (*(char const *)&little)
        return crc32c_sw_little(crc, buf, len);
    else
        return crc32c_sw_big(crc, buf, len);
}


================================================
FILE: ccan/ccan/crc32c/crc32c.h
================================================
/* Licensed under MIT - see LICENSE file for details */
#ifndef CCAN_CRC32C_H
#define CCAN_CRC32C_H
#include <stdint.h>
#include <stdlib.h>

/**
 * crc32c - Castagnoli 32 bit crc of string of bytes
 * @start_crc: the initial crc (usually 0)
 * @buf: pointer to bytes
 * @size: length of buffer
 *
 * If you don't know what crc32 to use, use this one: it's the best.
 *
 * @Article{castagnoli-crc,
 * author =       { Guy Castagnoli and Stefan Braeuer and Martin Herrman},
 * title =        {{Optimization of Cyclic Redundancy-Check Codes with 24
 *                 and 32 Parity Bits}},
 * journal =      IEEE Transactions on Communication,
 * year =         {1993},
 * volume =       {41},
 * number =       {6},
 * pages =        {},
 * month =        {June},
 *}
 * 32 bit CRC checksum using polynomial
 * X^32+X^28+X^27+X^26+X^25+X^23+X^22+X^20+X^19+X^18+X^14+X^13+X^11+X^10+X^9+X^8+X^6+X^0.
 *
 * You can calculate the CRC of non-contiguous arrays by passing @start_crc
 * as 0 the first time, and the current crc result from then on.
 *
 * Example:
 *	#include <sys/uio.h>
 *	...
 *	// Check that iovec has the crc we expect (Castagnoli version)
 *	static bool check_crc(uint32_t expected, const struct iovec *iov, int l)
 *	{
 *		uint32_t crc = 0;
 *		while (l >= 0) {
 *			crc = crc32c(crc, iov->iov_base, iov->iov_len);
 *			iov++;
 *		}
 *		return crc == expected;
 *	}
 */
uint32_t crc32c(uint32_t start_crc, const void *buf, size_t size);

#endif /* CCAN_CRC32C_H */


================================================
FILE: ccan/ccan/crc32c/test/api-crc32c.c
================================================
/* Test vectors from https://tools.ietf.org/html/rfc3720#appendix-B.4 */
#include <ccan/crc32c/crc32c.h>
#include <ccan/tap/tap.h>
#include <string.h>

#define BSWAP_32(val)					\
	((((uint32_t)(val) & 0x000000ff) << 24)		\
	 | (((uint32_t)(val) & 0x0000ff00) << 8)		\
	 | (((uint32_t)(val) & 0x00ff0000) >> 8)		\
	 | (((uint32_t)(val) & 0xff000000) >> 24))

#if HAVE_LITTLE_ENDIAN
#define BE32_TO_CPU(le_val) BSWAP_32((uint32_t)le_val)
#else
#define BE32_TO_CPU(le_val) ((uint32_t)(le_val))
#endif

int main(void)
{
	unsigned char m[48];

	plan_tests(5);

	/* 32 bytes of zeroes:

     Byte:        0  1  2  3

        0:       00 00 00 00
      ...
       28:       00 00 00 00

      CRC:       aa 36 91 8a
	*/

	memset(m, 0, 32);
	ok1(crc32c(0, m, 32) == BE32_TO_CPU(0xaa36918a));

	/* 32 bytes of ones:

     Byte:        0  1  2  3

        0:       ff ff ff ff
      ...
       28:       ff ff ff ff

      CRC:       43 ab a8 62
	*/
	memset(m, 0xff, 32);
	ok1(crc32c(0, m, 32) == BE32_TO_CPU(0x43aba862));

	/* 32 bytes of incrementing 00..1f:

     Byte:        0  1  2  3

        0:       00 01 02 03
      ...
       28:       1c 1d 1e 1f

      CRC:       4e 79 dd 46
	*/
	for (size_t i = 0; i < 32; i++)
		m[i] = i;
	ok1(crc32c(0, m, 32) == BE32_TO_CPU(0x4e79dd46));

	/*  32 bytes of decrementing 1f..00:

     Byte:        0  1  2  3

        0:       1f 1e 1d 1c
      ...
       28:       03 02 01 00

      CRC:       5c db 3f 11
	*/
	for (size_t i = 0; i < 32; i++)
		m[i] = 31 - i;
	ok1(crc32c(0, m, 32) == BE32_TO_CPU(0x5cdb3f11));

	/*  An iSCSI - SCSI Read (10) Command PDU
    Byte:        0  1  2  3

       0:       01 c0 00 00
       4:       00 00 00 00
       8:       00 00 00 00
      12:       00 00 00 00
      16:       14 00 00 00
      20:       00 00 04 00
      24:       00 00 00 14
      28:       00 00 00 18
      32:       28 00 00 00
      36:       00 00 00 00
      40:       02 00 00 00
      44:       00 00 00 00

     CRC:       56 3a 96 d9
	*/
	memset(m, 0, sizeof(m));
	m[0] = 0x01;
	m[1] = 0xc0;
	m[16] = 0x14;
	m[22] = 0x04;
	m[27] = 0x14;
	m[31] = 0x18;
	m[32] = 0x28;
	m[40] = 0x02;
	ok1(crc32c(0, m, sizeof(m)) == BE32_TO_CPU(0x563a96d9));

	return exit_status();
}


================================================
FILE: ccan/ccan/crc32c/test/run-crc32c.c
================================================
/* Test vectors from https://tools.ietf.org/html/rfc3720#appendix-B.4 */

/* Get access to sw version explicitly */
#include <ccan/crc32c/crc32c.c>
#include <ccan/tap/tap.h>
#include <string.h>

#define BSWAP_32(val)					\
	((((uint32_t)(val) & 0x000000ff) << 24)		\
	 | (((uint32_t)(val) & 0x0000ff00) << 8)		\
	 | (((uint32_t)(val) & 0x00ff0000) >> 8)		\
	 | (((uint32_t)(val) & 0xff000000) >> 24))

#if HAVE_LITTLE_ENDIAN
#define BE32_TO_CPU(le_val) BSWAP_32((uint32_t)le_val)
#else
#define BE32_TO_CPU(le_val) ((uint32_t)(le_val))
#endif

int main(void)
{
	unsigned char m[48];

	plan_tests(5);

	/* 32 bytes of zeroes:

     Byte:        0  1  2  3

        0:       00 00 00 00
      ...
       28:       00 00 00 00

      CRC:       aa 36 91 8a
	*/

	memset(m, 0, 32);
	ok1(crc32c_sw(0, m, 32) == BE32_TO_CPU(0xaa36918a));

	/* 32 bytes of ones:

     Byte:        0  1  2  3

        0:       ff ff ff ff
      ...
       28:       ff ff ff ff

      CRC:       43 ab a8 62
	*/
	memset(m, 0xff, 32);
	ok1(crc32c_sw(0, m, 32) == BE32_TO_CPU(0x43aba862));

	/* 32 bytes of incrementing 00..1f:

     Byte:        0  1  2  3

        0:       00 01 02 03
      ...
       28:       1c 1d 1e 1f

      CRC:       4e 79 dd 46
	*/
	for (size_t i = 0; i < 32; i++)
		m[i] = i;
	ok1(crc32c_sw(0, m, 32) == BE32_TO_CPU(0x4e79dd46));

	/*  32 bytes of decrementing 1f..00:

     Byte:        0  1  2  3

        0:       1f 1e 1d 1c
      ...
       28:       03 02 01 00

      CRC:       5c db 3f 11
	*/
	for (size_t i = 0; i < 32; i++)
		m[i] = 31 - i;
	ok1(crc32c_sw(0, m, 32) == BE32_TO_CPU(0x5cdb3f11));

	/*  An iSCSI - SCSI Read (10) Command PDU
    Byte:        0  1  2  3

       0:       01 c0 00 00
       4:       00 00 00 00
       8:       00 00 00 00
      12:       00 00 00 00
      16:       14 00 00 00
      20:       00 00 04 00
      24:       00 00 00 14
      28:       00 00 00 18
      32:       28 00 00 00
      36:       00 00 00 00
      40:       02 00 00 00
      44:       00 00 00 00

     CRC:       56 3a 96 d9
	*/
	memset(m, 0, sizeof(m));
	m[0] = 0x01;
	m[1] = 0xc0;
	m[16] = 0x14;
	m[22] = 0x04;
	m[27] = 0x14;
	m[31] = 0x18;
	m[32] = 0x28;
	m[40] = 0x02;
	ok1(crc32c_sw(0, m, sizeof(m)) == BE32_TO_CPU(0x563a96d9));

	return exit_status();
}


================================================
FILE: config.mk
================================================
TOPDIR ?= $(CURDIR)

VER ?= $(shell awk '/Version/ {print $$2}'  $(TOPDIR)/mhvtl-utils.spec)
REL ?= $(shell awk -F'[ %]' '/Release/ {print $$2}' $(TOPDIR)/mhvtl-utils.spec)
EXTRAVERSION ?= $(shell awk '/define minor/ {print $$3}' $(TOPDIR)/mhvtl-utils.spec)

FIRMWAREDIR ?= $(shell awk '/^%.*_firmwarepath/ {print $$3}' $(TOPDIR)/mhvtl-utils.spec)

GITHASH ?= $(if $(shell test -d $(TOPDIR)/.git && echo 1),commit:\ $(shell git show -s --format=%h))
GITDATE ?= $(if $(shell test -d $(TOPDIR)/.git && echo 1),$(shell git show -s --format=%aI))

VERSION ?= $(VER)

PREFIX ?= /usr
MANDIR ?= /share/man

MHVTL_HOME_PATH ?= /opt/mhvtl
MHVTL_CONFIG_PATH ?= /etc/mhvtl
SYSTEMD_GENERATOR_DIR ?= /lib/systemd/system-generators
SYSTEMD_SERVICE_DIR ?= /lib/systemd/system

ifeq ($(shell whoami),root)
ROOTUID = YES
endif

ifeq ($(shell grep lib64$ /etc/ld.so.conf /etc/ld.so.conf.d/* | wc -l),0)
LIBDIR ?= $(PREFIX)/lib
else
LIBDIR ?= $(PREFIX)/lib64
endif

-include $(TOPDIR)/local.mk

HOME_PATH = $(subst /,\/,$(MHVTL_HOME_PATH))
CONFIG_PATH = $(subst /,\/,$(MHVTL_CONFIG_PATH))


================================================
FILE: doc/4_library_example/device.conf
================================================

VERSION: 3

# VPD page format:
# <page #> <Length> <x> <x+1>... <x+n>
# NAA format is an 8 hex byte value seperated by ':'
# Note: NAA is part of inquiry VPD 0x83
#
# Each 'record' is sperated by one (or more) blank lines.
# Each 'record' starts at column 1

Library: 10 CHANNEL: 0 TARGET: 1 LUN: 0
 Vendor identification: SPECTRA
 Product identification: PYTHON
 Product revision level: 5500
 Unit serial number: XYZZY_10
 NAA: 10:22:33:44:ab:cd:ef:00

Drive: 11 CHANNEL: 0 TARGET: 1 LUN: 1
 Library ID: 10 Slot: 1
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_11
 NAA: 10:22:33:44:ab:cd:ef:01
 VPD: b0 04 00 02 01 00

Drive: 12 CHANNEL: 0 TARGET: 1 LUN: 2
 Library ID: 10 Slot: 2
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_12
 NAA: 10:22:33:44:ab:cd:ef:02
 VPD: b0 04 00 02 01 00

Drive: 13 CHANNEL: 0 TARGET: 1 LUN: 3
 Library ID: 10 Slot: 3
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_13
 NAA: 10:22:33:44:ab:cd:ef:03
 VPD: b0 04 00 02 01 00

Drive: 14 CHANNEL: 0 TARGET: 1 LUN: 4
 Library ID: 10 Slot: 4
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_14
 NAA: 10:22:33:44:ab:cd:ef:04
 VPD: b0 04 00 02 01 00

Drive: 15 CHANNEL: 0 TARGET: 1 LUN: 5
 Library ID: 10 Slot: 5
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_15
 NAA: 10:22:33:44:ab:cd:ef:05
 VPD: b0 04 00 02 01 00

Drive: 16 CHANNEL: 0 TARGET: 1 LUN: 6
 Library ID: 10 Slot: 6
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_16
 NAA: 10:22:33:44:ab:cd:ef:06
 VPD: b0 04 00 02 01 00

Drive: 17 CHANNEL: 0 TARGET: 1 LUN: 7
 Library ID: 10 Slot: 7
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_17
 NAA: 10:22:33:44:ab:cd:ef:07
 VPD: b0 04 00 02 01 00

Drive: 18 CHANNEL: 0 TARGET: 1 LUN: 8
 Library ID: 10 Slot: 8
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_18
 NAA: 10:22:33:44:ab:cd:ef:08
 VPD: b0 04 00 02 01 00

Drive: 19 CHANNEL: 0 TARGET: 1 LUN: 9
 Library ID: 10 Slot: 9
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_19
 NAA: 10:22:33:44:ab:cd:ef:09
 VPD: b0 04 00 02 01 00

Library: 20 CHANNEL: 0 TARGET: 1 LUN: 10
 Vendor identification: SPECTRA
 Product identification: PYTHON
 Product revision level: 5500
 Unit serial number: XYZZY_20
 NAA: 20:22:33:44:ab:cd:ef:00

Drive: 21 CHANNEL: 0 TARGET: 1 LUN: 11
 Library ID: 20 Slot: 1
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_21
 NAA: 20:22:33:44:ab:cd:ef:01
 VPD: b0 04 00 02 01 00

Drive: 22 CHANNEL: 0 TARGET: 1 LUN: 12
 Library ID: 20 Slot: 2
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_22
 NAA: 20:22:33:44:ab:cd:ef:02
 VPD: b0 04 00 02 01 00

Drive: 23 CHANNEL: 0 TARGET: 1 LUN: 13
 Library ID: 20 Slot: 3
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_23
 NAA: 20:22:33:44:ab:cd:ef:03
 VPD: b0 04 00 02 01 00

Drive: 24 CHANNEL: 0 TARGET: 1 LUN: 14
 Library ID: 20 Slot: 4
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_24
 NAA: 20:22:33:44:ab:cd:ef:04
 VPD: b0 04 00 02 01 00

Drive: 25 CHANNEL: 0 TARGET: 1 LUN: 15
 Library ID: 20 Slot: 5
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_25
 NAA: 20:22:33:44:ab:cd:ef:05
 VPD: b0 04 00 02 01 00

Drive: 26 CHANNEL: 0 TARGET: 1 LUN: 16
 Library ID: 20 Slot: 6
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_26
 NAA: 20:22:33:44:ab:cd:ef:06
 VPD: b0 04 00 02 01 00

Drive: 27 CHANNEL: 0 TARGET: 1 LUN: 17
 Library ID: 20 Slot: 7
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_27
 NAA: 20:22:33:44:ab:cd:ef:07
 VPD: b0 04 00 02 01 00

Drive: 28 CHANNEL: 0 TARGET: 1 LUN: 18
 Library ID: 20 Slot: 8
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_28
 NAA: 20:22:33:44:ab:cd:ef:08
 VPD: b0 04 00 02 01 00

Drive: 29 CHANNEL: 0 TARGET: 1 LUN: 19
 Library ID: 20 Slot: 9
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_29
 NAA: 20:22:33:44:ab:cd:ef:09
 VPD: b0 04 00 02 01 00

Library: 30 CHANNEL: 0 TARGET: 1 LUN: 20
 Vendor identification: SPECTRA
 Product identification: PYTHON
 Product revision level: 5500
 Unit serial number: XYZZY_30
 NAA: 30:22:33:44:ab:cd:ef:00

Drive: 31 CHANNEL: 0 TARGET: 1 LUN: 21
 Library ID: 30 Slot: 1
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_31
 NAA: 30:22:33:44:ab:cd:ef:01
 VPD: b0 04 00 02 01 00

Drive: 32 CHANNEL: 0 TARGET: 1 LUN: 22
 Library ID: 30 Slot: 2
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_32
 NAA: 30:22:33:44:ab:cd:ef:02
 VPD: b0 04 00 02 01 00

Drive: 33 CHANNEL: 0 TARGET: 1 LUN: 23
 Library ID: 30 Slot: 3
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_33
 NAA: 30:22:33:44:ab:cd:ef:03
 VPD: b0 04 00 02 01 00

Drive: 34 CHANNEL: 0 TARGET: 1 LUN: 24
 Library ID: 30 Slot: 4
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_34
 NAA: 30:22:33:44:ab:cd:ef:04
 VPD: b0 04 00 02 01 00

Drive: 35 CHANNEL: 0 TARGET: 1 LUN: 25
 Library ID: 30 Slot: 5
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_35
 NAA: 30:22:33:44:ab:cd:ef:05
 VPD: b0 04 00 02 01 00

Drive: 36 CHANNEL: 0 TARGET: 1 LUN: 26
 Library ID: 30 Slot: 6
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_36
 NAA: 30:22:33:44:ab:cd:ef:06
 VPD: b0 04 00 02 01 00

Drive: 37 CHANNEL: 0 TARGET: 1 LUN: 27
 Library ID: 30 Slot: 7
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_37
 NAA: 30:22:33:44:ab:cd:ef:07
 VPD: b0 04 00 02 01 00

Drive: 38 CHANNEL: 0 TARGET: 1 LUN: 28
 Library ID: 30 Slot: 8
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_38
 NAA: 30:22:33:44:ab:cd:ef:08
 VPD: b0 04 00 02 01 00

Drive: 39 CHANNEL: 0 TARGET: 1 LUN: 29
 Library ID: 30 Slot: 9
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_39
 NAA: 30:22:33:44:ab:cd:ef:09
 VPD: b0 04 00 02 01 00

Library: 40 CHANNEL: 0 TARGET: 1 LUN: 30
 Vendor identification: SPECTRA
 Product identification: PYTHON
 Product revision level: 5500
 Unit serial number: XYZZY_40
 NAA: 40:22:33:44:ab:cd:ef:00

Drive: 41 CHANNEL: 0 TARGET: 1 LUN: 31
 Library ID: 40 Slot: 1
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_41
 NAA: 40:22:33:44:ab:cd:ef:01
 VPD: b0 04 00 02 01 00

Drive: 42 CHANNEL: 0 TARGET: 2 LUN: 0
 Library ID: 40 Slot: 2
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_42
 NAA: 40:22:33:44:ab:cd:ef:02
 VPD: b0 04 00 02 01 00

Drive: 43 CHANNEL: 0 TARGET: 2 LUN: 1
 Library ID: 40 Slot: 3
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_43
 NAA: 40:22:33:44:ab:cd:ef:03
 VPD: b0 04 00 02 01 00

Drive: 44 CHANNEL: 0 TARGET: 2 LUN: 2
 Library ID: 40 Slot: 4
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_44
 NAA: 40:22:33:44:ab:cd:ef:04
 VPD: b0 04 00 02 01 00

Drive: 45 CHANNEL: 0 TARGET: 2 LUN: 3
 Library ID: 40 Slot: 5
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_45
 NAA: 40:22:33:44:ab:cd:ef:05
 VPD: b0 04 00 02 01 00

Drive: 46 CHANNEL: 0 TARGET: 2 LUN: 4
 Library ID: 40 Slot: 6
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_46
 NAA: 40:22:33:44:ab:cd:ef:06
 VPD: b0 04 00 02 01 00

Drive: 47 CHANNEL: 0 TARGET: 2 LUN: 5
 Library ID: 40 Slot: 7
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_47
 NAA: 40:22:33:44:ab:cd:ef:07
 VPD: b0 04 00 02 01 00

Drive: 48 CHANNEL: 0 TARGET: 2 LUN: 6
 Library ID: 40 Slot: 8
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_48
 NAA: 40:22:33:44:ab:cd:ef:08
 VPD: b0 04 00 02 01 00

Drive: 49 CHANNEL: 0 TARGET: 2 LUN: 7
 Library ID: 40 Slot: 9
 Vendor identification: QUANTUM
 Product identification: SDLT600
 Product revision level: 5500
 Unit serial number: XYZZY_49
 NAA: 40:22:33:44:ab:cd:ef:09
 VPD: b0 04 00 02 01 00



================================================
FILE: doc/4_library_example/library_contents.10
================================================
VERSION: 2

Drive 1:
Drive 2:
Drive 3:
Drive 4:
Drive 5:
Drive 6:
Drive 7:
Drive 8:
Drive 9:

Picker 1:

MAP 1:
MAP 2:
MAP 3:
MAP 4:

# Slot 1 - ?, no gaps
# Slot N: [barcode]
# [barcode]
# a barcode is comprised of three fields: [Leading] [identifier] [Trailing]
# Leading "CLN" -- cleaning tape
# Leading "W" -- WORM tape
# Leading "NOBAR" -- will appear to have no barcode
# If the barcode is at least 8 character long, then the last two characters are
Trailing
# Trailing "S3" - SDLT600
# Trailing "X4" - AIT-4
# Trailing "L1" - LTO 1
# Trailing "TA" - T10000+
# Trailing "JA" - 3592+
# Trailing "JB" - 3592E05+
# Trailing "JW" - WORM 3592+
# Trailing "JX" - WORM 3592E05+
#
Slot 01: L10001S3
Slot 02: L10002S3
Slot 03: L10003S3
Slot 04: L10004S3
Slot 05: L10005S3
Slot 06: L10006S3
Slot 07: L10007S3
Slot 08: L10008S3
Slot 09: L10009S3
Slot 10: L10010S3
Slot 11: L10011S3
Slot 12: L10012S3
Slot 13: L10013S3
Slot 14: L10014S3
Slot 15: L10015S3
Slot 16: L10016S3
Slot 17: L10017S3
Slot 18: L10018S3
Slot 19: L10019S3
Slot 20: L10020S3
Slot 21: L10021S3
Slot 22: L10022S3
Slot 23: L10023S3
Slot 24: L10024S3
Slot 25: L10025S3
Slot 26: L10026S3
Slot 27: L10027S3
Slot 28: L10028S3
Slot 29: L10029S3
Slot 30: L10030S3
Slot 31: L10031S3
Slot 32: L10032S3
Slot 33: L10033S3
Slot 34: L10034S3
Slot 35: L10035S3
Slot 36: L10036S3
Slot 37: L10037S3
Slot 38: L10038S3
Slot 39: L10039S3
Slot 40: L10040S3
Slot 41: L10041S3
Slot 42: L10042S3
Slot 43: L10043S3
Slot 44: L10044S3
Slot 45: L10045S3
Slot 46: L10046S3
Slot 47: L10047S3
Slot 48: L10048S3
Slot 49: L10049S3
Slot 50: L10050S3


================================================
FILE: doc/4_library_example/library_contents.20
================================================
VERSION: 2

Drive 1:
Drive 2:
Drive 3:
Drive 4:
Drive 5:
Drive 6:
Drive 7:
Drive 8:
Drive 9:

Picker 1:

MAP 1:
MAP 2:
MAP 3:
MAP 4:

# Slot 1 - ?, no gaps
# Slot N: [barcode]
# [barcode]
# a barcode is comprised of three fields: [Leading] [identifier] [Trailing]
# Leading "CLN" -- cleaning tape
# Leading "W" -- WORM tape
# Leading "NOBAR" -- will appear to have no barcode
# If the barcode is at least 8 character long, then the last two characters are
Trailing
# Trailing "S3" - SDLT600
# Trailing "X4" - AIT-4
# Trailing "L1" - LTO 1
# Trailing "TA" - T10000+
# Trailing "JA" - 3592+
# Trailing "JB" - 3592E05+
# Trailing "JW" - WORM 3592+
# Trailing "JX" - WORM 3592E05+
#
Slot 01: L20001S3
Slot 02: L20002S3
Slot 03: L20003S3
Slot 04: L20004S3
Slot 05: L20005S3
Slot 06: L20006S3
Slot 07: L20007S3
Slot 08: L20008S3
Slot 09: L20009S3
Slot 10: L20010S3
Slot 11: L20011S3
Slot 12: L20012S3
Slot 13: L20013S3
Slot 14: L20014S3
Slot 15: L20015S3
Slot 16: L20016S3
Slot 17: L20017S3
Slot 18: L20018S3
Slot 19: L20019S3
Slot 20: L20020S3
Slot 21: L20021S3
Slot 22: L20022S3
Slot 23: L20023S3
Slot 24: L20024S3
Slot 25: L20025S3
Slot 26: L20026S3
Slot 27: L20027S3
Slot 28: L20028S3
Slot 29: L20029S3
Slot 30: L20030S3
Slot 31: L20031S3
Slot 32: L20032S3
Slot 33: L20033S3
Slot 34: L20034S3
Slot 35: L20035S3
Slot 36: L20036S3
Slot 37: L20037S3
Slot 38: L20038S3
Slot 39: L20039S3
Slot 40: L20040S3
Slot 41: L20041S3
Slot 42: L20042S3
Slot 43: L20043S3
Slot 44: L20044S3
Slot 45: L20045S3
Slot 46: L20046S3
Slot 47: L20047S3
Slot 48: L20048S3
Slot 49: L20049S3
Slot 50: L20050S3


================================================
FILE: doc/4_library_example/library_contents.30
================================================
VERSION: 2

Drive 1:
Drive 2:
Drive 3:
Drive 4:
Drive 5:
Drive 6:
Drive 7:
Drive 8:
Drive 9:

Picker 1:

MAP 1:
MAP 2:
MAP 3:
MAP 4:

# Slot 1 - ?, no gaps
# Slot N: [barcode]
# [barcode]
# a barcode is comprised of three fields: [Leading] [identifier] [Trailing]
# Leading "CLN" -- cleaning tape
# Leading "W" -- WORM tape
# Leading "NOBAR" -- will appear to have no barcode
# If the barcode is at least 8 character long, then the last two characters are
Trailing
# Trailing "S3" - SDLT600
# Trailing "X4" - AIT-4
# Trailing "L1" - LTO 1
# Trailing "TA" - T10000+
# Trailing "JA" - 3592+
# Trailing "JB" - 3592E05+
# Trailing "JW" - WORM 3592+
# Trailing "JX" - WORM 3592E05+
#
Slot 01: L30001S3
Slot 02: L30002S3
Slot 03: L30003S3
Slot 04: L30004S3
Slot 05: L30005S3
Slot 06: L30006S3
Slot 07: L30007S3
Slot 08: L30008S3
Slot 09: L30009S3
Slot 10: L30010S3
Slot 11: L30011S3
Slot 12: L30012S3
Slot 13: L30013S3
Slot 14: L30014S3
Slot 15: L30015S3
Slot 16: L30016S3
Slot 17: L30017S3
Slot 18: L30018S3
Slot 19: L30019S3
Slot 20: L30020S3
Slot 21: L30021S3
Slot 22: L30022S3
Slot 23: L30023S3
Slot 24: L30024S3
Slot 25: L30025S3
Slot 26: L30026S3
Slot 27: L30027S3
Slot 28: L30028S3
Slot 29: L30029S3
Slot 30: L30030S3
Slot 31: L30031S3
Slot 32: L30032S3
Slot 33: L30033S3
Slot 34: L30034S3
Slot 35: L30035S3
Slot 36: L30036S3
Slot 37: L30037S3
Slot 38: L30038S3
Slot 39: L30039S3
Slot 40: L30040S3
Slot 41: L30041S3
Slot 42: L30042S3
Slot 43: L30043S3
Slot 44: L30044S3
Slot 45: L30045S3
Slot 46: L30046S3
Slot 47: L30047S3
Slot 48: L30048S3
Slot 49: L30049S3
Slot 50: L30050S3


================================================
FILE: doc/4_library_example/library_contents.40
================================================
VERSION: 2

Drive 1:
Drive 2:
Drive 3:
Drive 4:
Drive 5:
Drive 6:
Drive 7:
Drive 8:
Drive 9:

Picker 1:

MAP 1:
MAP 2:
MAP 3:
MAP 4:

# Slot 1 - ?, no gaps
# Slot N: [barcode]
# [barcode]
# a barcode is comprised of three fields: [Leading] [identifier] [Trailing]
# Leading "CLN" -- cleaning tape
# Leading "W" -- WORM tape
# Leading "NOBAR" -- will appear to have no barcode
# If the barcode is at least 8 character long, then the last two characters are
Trailing
# Trailing "S3" - SDLT600
# Trailing "X4" - AIT-4
# Trailing "L1" - LTO 1
# Trailing "TA" - T10000+
# Trailing "JA" - 3592+
# Trailing "JB" - 3592E05+
# Trailing "JW" - WORM 3592+
# Trailing "JX" - WORM 3592E05+
#
Slot 01: L40001S3
Slot 02: L40002S3
Slot 03: L40003S3
Slot 04: L40004S3
Slot 05: L40005S3
Slot 06: L40006S3
Slot 07: L40007S3
Slot 08: L40008S3
Slot 09: L40009S3
Slot 10: L40010S3
Slot 11: L40011S3
Slot 12: L40012S3
Slot 13: L40013S3
Slot 14: L40014S3
Slot 15: L40015S3
Slot 16: L40016S3
Slot 17: L40017S3
Slot 18: L40018S3
Slot 19: L40019S3
Slot 20: L40020S3
Slot 21: L40021S3
Slot 22: L40022S3
Slot 23: L40023S3
Slot 24: L40024S3
Slot 25: L40025S3
Slot 26: L40026S3
Slot 27: L40027S3
Slot 28: L40028S3
Slot 29: L40029S3
Slot 30: L40030S3
Slot 31: L40031S3
Slot 32: L40032S3
Slot 33: L40033S3
Slot 34: L40034S3
Slot 35: L40035S3
Slot 36: L40036S3
Slot 37: L40037S3
Slot 38: L40038S3
Slot 39: L40039S3
Slot 40: L40040S3
Slot 41: L40041S3
Slot 42: L40042S3
Slot 43: L40043S3
Slot 44: L40044S3
Slot 45: L40045S3
Slot 46: L40046S3
Slot 47: L40047S3
Slot 48: L40048S3
Slot 49: L40049S3
Slot 50: L40050S3


================================================
FILE: doc/4_library_example/mhvtl.conf
================================================

# Home directory for config file(s)
MHVTL_CONFIG_PATH=/etc/mhvtl

# Default media capacity (5 G)
CAPACITY=5000

# Set default verbosity [0|1]
VERBOSE=0

# Set kernel module debugging [0|1]
VTL_DEBUG=0


================================================
FILE: doc/index.html
================================================
<html>

<h1 align="center">Welcome to Mark Harvey's home page</h1>

<hr width="80%">

<h2 align="center">Current projects:</h2>
	<ul>
	<li><a href="#vtl">Virtual Tape Library</a>
		<ul>
		<li><a href="#vtl-intro">Introduction</a>
		<li><a href="#vtl-vtltape">vtltape daemon</a>
		<li><a href="#vtl-vtllibrary">vtllibrary daemon</a>
		<li><a href="#vtl-vtlcmd">vtlcmd control utility</a>
		<li><a href="#vtl-examples-lsscsi">Operational examples (lsscsi -g)</a>
		<li><a href="#vtl-examples-tpautoconf">Operational examples (tpautoconf)</a>
		<li><a href="#vtl-examples-robtest">Operational examples (robtest)</a>
		<li><a href="#vtl-examples-TapeAlert">TapeAlert examples</a>
		<li><a href="#vtl-download">Download</a>
		</ul>
	</ul>

<hr width="80%">

<a NAME="vtl-intro"></a>
	<h2 align="left">Virtual Tape Library:</h2>
	<p>Virtual Tape Library consists of several components.</p>

	<ul>
	<li>LLD - A low level driver implemented as a kernel module - vx_tape</li>
	<li>Target devices - Daemons <b>vtltape(1)</b> and <b>vtllibrary(1)</b> which implement SCSI target device(s) in user-space</li>
	<li>Utility commands <b>mktape(1)</b>, <b>vtlcmd(1)</b></li>
	<li>And setup script <b>make_vtl_media(1)</b></li>
	</ul>


<p>
The kernel module is based on the scsi_debug kernel module
(<a href=http://www.torque.net/sg/sdebug26.html>http://www.torque.net/sg/sdebug26.html</a>).
vx_tape is a pseudo HBA (LLD) reporting it has 1 x SMC target (StorageTek L700)
and 8 x SSC targets (4 x IBM Ultrium-TD3 and 4 x Quantum SuperDLT600)
attached.
</p>

<p>
A char device back-end has been included with the vx_tape LLD
driver This allows data and SCSI commands to be passed from the LLD
to user-mode daemons (SCSI targets) which constently poll the driver
and process any outstanding SCSI commands.
<p>

<p>
<a NAME="vtl-vtltape"></a>
<h3>vtltape</h3>
<b>vtltape(1)</b> is the usermode SSC target daemon which writes/reads
 data to data files in the /opt/vtl directory
(if  a virtual tape has been loaded). The virtual tape files include a
Medium Auxiliary Memory (MAM) data structure to store  persistent  data
(number of tape loads, total data written/read, media type etc).
</p>

<p>
<a NAME="vtl-vtllibrary"></a>
<h3>vtllibrary</h3>
<b>vtllibrary(1)</b> is the usermode SMC target daemon which reads its
configuration from the file /etc/vtl/<b>library_contents(5)</b>
at startup. The number of storage slots are built dynamically
when the daemon starts. Hence changing the number of storage slots and
media access slots are a matter of modifing the file contents and
restarting  the  vtllibrary(1)  daemon. All 'library' commands are
performed on data structures in memory ONLY.
</p>

<p>
<a NAME="vtl-vtlcmd"></a>
<h3>vtlcmd</h3>
A utility <b>vtlcmd(1)</b> is used to administrator the daemons <b>vtltape(1)</b>
and <b>vtllibrary</b>.<br>
Message queue (key 0x4d61726b) is used to pass messages between
<b>vtlcmd(1)</b>, <b>vtllibrary(1)</b> and <b>vtltape(1)</b>
</p>

<p>
When a SCSI 'move medium' from a storage slot to a tape drive is requested,
the media location is updated in vtllibrary(1) data structures, and  the
barcode  of  the  media  id  is  passed  via  the  message queue to the
vtltape(1) daemon in question. A file open of the barcode  is  attempted
in  the /opt/vtl directory and if successful, the vtltape(1) daemon
will now return a ASC/ASCQ 0x0/0x0 to any Test Unit Ready requests.  An
unload SCSI command to the tape drive will close the data file.
</p>

<p>
Media can be moved out of the VTL via the Media Access Port. Once media
is logically moved into the MAP slots, the MAP entries can  be  cleared
using the vtlcmd:
</p>

<pre>
# vtlcmd library empty map
</pre>

<a NAME="vtl-examples-lsscsi"></a>
<h4>Examples</h4>

vx_tape is registered as HBA #3:
<pre>
# lsscsi -g
[0:0:0:0]    disk    MAXTOR   ATLAS10K4_36SCA  DFM0  /dev/sda  /dev/sg0
[0:0:6:0]    process PE/PV    1x3 SCSI BP      1.1   -         /dev/sg1
[2:0:0:0]    disk    SEAGATE  ST336607FC       0003  /dev/sdb  /dev/sg2
[2:0:1:0]    disk    SEAGATE  ST336607FC       0003  /dev/sdc  /dev/sg3
[2:0:2:0]    mediumx ATL      1500             6.0   -         /dev/sg4
[2:0:2:1]    tape    QUANTUM  SuperDLT1        2323  /dev/st0  /dev/sg5
[2:0:2:2]    tape    QUANTUM  SuperDLT1        2323  /dev/st1  /dev/sg6
[2:0:2:3]    process ATTO     310-LV           1.42  -         /dev/sg7
[3:0:0:0]    mediumx STK      L700             vx_0  -         /dev/sg8
[4:0:0:0]    tape    IBM      ULT3580-TD3      5400  /dev/st2  /dev/sg9
[4:0:0:1]    tape    IBM      ULT3580-TD3      5400  /dev/st3  /dev/sg10
[4:0:0:2]    tape    IBM      ULT3580-TD3      5400  /dev/st4  /dev/sg11
[4:0:0:3]    tape    IBM      ULT3580-TD3      5400  /dev/st5  /dev/sg12
[4:0:0:4]    tape    QUANTUM  SDLT600          5400  /dev/st6  /dev/sg13
[4:0:0:5]    tape    QUANTUM  SDLT600          5400  /dev/st7  /dev/sg14
[4:0:0:6]    tape    QUANTUM  SDLT600          5400  /dev/st8  /dev/sg15
[4:0:0:7]    tape    QUANTUM  SDLT600          5400  /dev/st9  /dev/sg16
</pre>

<a NAME="vtl-examples-tpautoconf"></a>
NetBackup Utilities:
<pre>
# tpautoconf -r
TPAC45 STK     L700            vx_0 8000 -1 -1 -1 -1 /dev/sg/h3c0t0l0 - -

# tpautoconf -t
TPAC45 IBM     ULT3580-TD3     5400 8001 -1 -1 -1 -1 /dev/st/nh3c0t0l1 - TapeAlert enabled
TPAC45 IBM     ULT3580-TD3     5400 8002 -1 -1 -1 -1 /dev/st/nh3c0t0l2 - TapeAlert enabled
TPAC45 IBM     ULT3580-TD3     5400 8003 -1 -1 -1 -1 /dev/st/nh3c0t0l3 - TapeAlert enabled
TPAC45 IBM     ULT3580-TD3     5400 8004 -1 -1 -1 -1 /dev/st/nh3c0t0l4 - TapeAlert enabled
TPAC45 QUANTUM SDLT600         5400 8005 -1 -1 -1 -1 /dev/st/nh3c0t0l5 - TapeAlert enabled
TPAC45 QUANTUM SDLT600         5400 8006 -1 -1 -1 -1 /dev/st/nh3c0t0l6 - TapeAlert enabled
TPAC45 QUANTUM SDLT600         5400 8007 -1 -1 -1 -1 /dev/st/nh3c0t0l7 - TapeAlert enabled
TPAC45 QUANTUM SDLT600         5400 8008 -1 -1 -1 -1 /dev/st/nh3c0t0l8 - TapeAlert enabled

</pre>

<p>
 <a href=http://sites.google.com/site/linuxvtl2/scan.txt>volmgr/bin/scan output</a> </p>

<a NAME="vtl-examples-robtest"></a>
<h4>Robot Inventory:</h4>

<p> <a href=http://sites.google.com/site/linuxvtl2/mtx.txt>Using mtx</a> </p>
<p> <a href=http://sites.google.com/site/linuxvtl2/robtest.txt>Using robtest</a> </p>

A sample /etc/vtl/library_contents can be <a href=http://sites.google.com/site/linuxvtl2/library_contents.txt>viewed via this link.</a>


<a NAME="vtl-examples-TapeAlert"></a>
<h3>TapeAlert</h3>
<p>TapeAlert flags can be set using the <b>vtlcmd(1)</b></p>
<p>e.g. vtlcmd [index|library] TapeAlert [flags]</p>
<p>Where index is the message Q offset (or string 'library') associated with the drive.</p>
<p>e.g. To set flag 14h (Clean now) the 20th bit (14h) needs to be set:<br>
Pull out the binary to decimal calculator<br>
1000 0000 0000 0000 0000 (20 bits) =&gt hex =&gt 80000</p>
<pre># vtlcmd 1 TapeAlert 80000</pre>
<p>A listing of TapeAlert flags can be found at <a href=http://www.t10.org/ftp/t10/drafts/ssc3/ssc3r01e.pdf>t10 home page for SSC devices</a>
Annex A.</p>

<table border="3">
<tr>
<th>Code</th>
<th>vtlcmd value</th>
<th>Flag</th>
<th>Type</th>
<th>Flag Type</th>
<th>Recommended application client message</th>
<th>Probable cause</th>
</tr>

<tr>
<td align="center">01h</td>
<td align="right">1</td>
<td>Read warning</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive is having problems reading data. No data has been lost, but there has been a reduction in the performance of the tape.</td>
<td>The drive is having severe trouble reading.</td>
</tr>

<tr>
<td align="center">02h</td>
<td align="right">2</td>
<td>Write warning</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive is having problems writing data. No
data has been lost, but there has been a reduction in
the capacity of the tape.</td>
<td>The drive is having severe trouble writing.</td>
</tr>

<tr>
<td align="center">03h</td>
<td align="right">4</td>
<td>Hard error</td>
<td align="center">M</td>
<td align="center">W</td>
<td>The operation has stopped because an error has
occurred while reading or writing data that the drive
cannot correct.</td>
<td>The drive had a hard
read or write error.</td>
</tr>

<tr>
<td align="center">04h</td>
<td align="right">8</td>
<td>Media</td>
<td align="center">M</td>
<td align="center">C</td>
<td>Your data is at risk:
<ol>
<li>Copy any data you require from this tape.<br>
<li>Do not use this tape again.<br>
<li>Restart the operation with a different tape.</td>
</ol>
<td>Media can no longer be written/read, or performance is severely degraded.</td>
</tr>

<tr>
<td align="center">05h</td>
<td align="right">10</td>
<td>Read failure</td>
<td align="center">M</td>
<td align="center">C</td>
<td>The tape is damaged or the drive is faulty. Call the tape drive supplier help line.</td>

<td>The drive can no longer read data from the tape.</td>
</tr>

<tr>
<td align="center">06h</td>
<td align="right">20</td>
<td>Write failure</td>
<td align="center">M</td>
<td align="center">C</td>
<td>The tape is from a faulty batch or the tape drive is
faulty:<br>
<ol>
<li>Use a good tape to test the drive.<br>
<li>If the problem persists, call the tape drive supplier help line.</td>
</ol>

<td>The drive can no longer write data to the tape.</td>
</tr>
<tr>
<td align="center">07h</td>
<td align="right">40</td>
<td>Media life</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape cartridge has reached the end of its calculated useful life:
<ol>
<li>Copy any data you need to another tape.<br>
<li>Discard the old tape.</td>
</ol>
<td>The media has exceeded its specified life.</td>
</tr>
<tr>
<td align="center">08h</td>
<td align="right">80</td>
<td>Not data grade</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The cartridge is not data-grade. Any data you write to the tape is at risk. Replace the cartridge with a data-grade tape.</td>
<td>The drive has not been able to read the MRSa stripes.</td>
</tr>

<tr>
<td align="center">09h</td>
<td align="right">100</td>
<td>Write protect</td>
<td align="center">O</td>
<td align="center">C</td>
<td>You are trying to write to a write protected cartridge.  Remove the write protection or use another tape.</td>
<td>Write command is attempted to a write protected tape.</td>
</tr>

<tr>
<td align="center">0Ah</td>
<td align="right">200</td>
<td>No removal</td>
<td align="center">O</td>
<td align="center">I</td>
<td>You cannot eject the cartridge because the tape drive is in use. Wait until the operation is complete before ejecting the cartridge.</td>
<td>Manual or software unload attempted when prevent media removal is on.</td>
</tr>

<tr>
<td align="center">0Bh</td>
<td align="right">400</td>
<td>Cleaning media</td>
<td align="center">O</td>
<td align="center">I</td>
<td>The tape in the drive is a cleaning cartridge. Cleaning tape loaded into drive.</td>
</tr>

<tr>
<td align="center">0Ch</td>
<td align="right">800</td>
<td>Unsupported format</td>
<td align="center">O</td>
<td align="center">I</td>
<td>You have tried to load a cartridge of a type that is not
supported by this drive.</td>
<td>Attempted load of unsupported tape format (e.g., DDS2 in DDS1 drive).</td>
</tr>

<tr>
<td align="center">0Dh</td>
<td align="right">1000</td>
<td>Recoverable mechanical cartridge failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The operation has failed because the tape in the
drive has experienced a mechanical failure:<br>
<ol>
<li>Discard the old tape.<br>
<li>Restart the operation with a different tape.</td>
</ol>
<td>Tape snapped/cut or other cartridge mechanical failure in the drive where medium can be de-mounted.</td>
</tr>

<tr>
<td align="center">0Eh</td>
<td align="right">2000</td>
<td>Unrecoverable mechanical cartridge failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The operation has failed because the tape in the
drive has experienced a mechanical failure:<br>
<ol>
<li>Do not attempt to extract the tape cartridge.<br>
<li>Call the tape drive supplier help line.</td>
</ol>
<td>Tape snapped/cut or other cartridge mechanical failure in the drive where medium cannot be de-mounted.</td>
</tr>

<tr>
<td align="center">0Fh</td>
<td align="right">4000</td>
<td>Memory chip in cartridge failure</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The memory in the tape cartridge has failed, which reduces performance. Do not use the cartridge for further write operations.</td>
<td>Memory chip failed in cartridge.</td>
</tr>

<td align="center">10h</td>
<td align="right">8000</td>
<td>Forced eject</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The operation has failed because the tape cartridge was manually de-mounted while the tape drive was actively writing or reading.</td>
<td>Manual or forced eject while drive actively writing or reading.</td>
</tr>

<tr>
<td align="center">11h</td>
<td align="right">10000</td>
<td>Read only format</td>
<td align="center">O</td>
<td align="center">W</td>
<td>You have loaded a cartridge of a type that is read-only in this drive. The cartridge will appear as write protected.</td>
<td>Media loaded that is read-only format.</td>
</tr>

<tr>
<td align="center">12h</td>
<td align="right">20000</td>
<td>Tape directory corrupted on load</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape directory on the tape cartridge has been corrupted. File search performance will be degraded.  The tape directory can be rebuilt by reading all the data on the cartridge.</td>
<td>Tape drive powered down with tape loaded, or permanent error prevented the tape directory being updated.</td>
</tr>

<tr>
<td align="center">13h</td>
<td align="right">40000</td>
<td>Nearing media life</td>
<td align="center">O</td>
<td align="center">I</td>
<td>The tape cartridge is nearing the end of its calculated life. It is recommended that you:<br>
<ol>
<li>Use another tape cartridge for your next backup.<br>
<li>Store this tape cartridge in a safe place in case you need to restore data from it.</td>
</ol>
<td>Media may have exceeded its specified number of passes.</td>
</tr>

<tr>
<td align="center">14h</td>
<td align="right">80000</td>
<td>Clean now</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The tape drive needs cleaning:<br>
<ol>
<li>If the operation has stopped, eject the tape and
clean the drive.
<li>If the operation has not stopped, wait for it to finish
and then clean the drive.
</ol>
Check the tape drive users manual for device specific
cleaning instructions.</td>
<td>The drive thinks it has a head clog or needs cleaning.</td>
</tr>

<tr>
<td align="center">15h</td>
<td align="right">100000</td>
<td>Clean periodic</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive is due for routine cleaning:
<ol>
<li>Wait for the current operation to finish.
<li>Then use a cleaning cartridge.
</ol></td>
<td>Check the tape drive users manual for device specific cleaning instructions.
The drive is ready for a periodic cleaning.</td>
</tr>

<tr>
<td align="center">16h</td>
<td align="right">200000</td>
<td>Expired cleaning media</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The last cleaning cartridge used in the tape drive has worn out:<br>
<ol>
<li>Discard the worn out cleaning cartridge.<br>
<li>Wait for the current operation to finish.<br>
<li>Then use a new cleaning cartridge.
</ol></td>
<td>The cleaning tape has expired.</td>
</tr>

<tr>
<td align="center">17h</td>
<td align="right">400000</td>
<td>Invalid cleaning tape</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The last cleaning cartridge used in the tape drive was
an invalid type:<br>
<ol>
<li>Do not use this cleaning cartridge in this drive.<br>
<li>Wait for the current operation to finish.<br>
<li>Then use a valid cleaning cartridge.
</ol></td>
<td>Invalid cleaning tape type used.</td>
</tr>

<tr>
<td align="center">18h</td>
<td align="right">800000</td>
<td>Retension requested</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive has requested a retension operation.</td>
<td>The drive is having severe trouble reading or writing, that will be resolved by a retension cycle.</td>
</tr>

<tr>
<td align="center">19h</td>
<td align="right">1000000</td>
<td>Dual-port interface error</td>
<td align="center">O</td>
<td align="center">W</td>
<td>A redundant interface port on the tape drive has failed.</td>
<td>Failure of one interface port in a dual-port configuration (i.e., Fibre Channel)</td>
</tr>

<tr>
<td align="center">1Ah</td>
<td align="right">2000000</td>
<td>Cooling fan failure</td>
<td align="center">O</td>
<td align="center">W</td>
<td>A tape drive cooling fan has failed.</td>
<td>Fan failure inside tape drive mechanism or tape drive enclosure.</td>
</tr>

<tr>
<td align="center">1Bh</td>
<td align="right">4000000</td>
<td>Power supply failure</td>
<td align="center">O</td>
<td align="center">W</td>
<td>A redundant power supply has failed inside the tape drive enclosure. Check the enclosure users manual for instructions on replacing the failed power supply.</td>
<td>Redundant PSU failure inside the tape drive enclosure or rack subsystem.</td>
</tr>

<tr>
<td align="center">1Ch</td>
<td align="right">8000000</td>
<td>Power consumption</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive power consumption is outside the specified range.</td>
<td>Power consumption of the tape drive is outside specified range.</td>
</tr>

<tr>
<td align="center">1Dh</td>
<td align="right">10000000</td>
<td>Drive maintenance</td>
<td align="center">O</td>
<td align="center">W</td>
<td>Preventive maintenance of the tape drive is required.  Check the tape drive users manual for device specific preventive maintenance tasks or call the tape drive supplier help line.</td>
<td>The drive requires preventive maintenance (not cleaning).</td>
</tr>

<td align="center">1Eh</td>
<td align="right">20000000</td>
<td>Hardware A</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The tape drive has a hardware fault:
<ol>
<li>Eject the tape or magazine.
<li>Reset the drive.
<li>Restart the operation.
</ol>
</td>
<td>The drive has a hardware fault that requires reset to recover.</td>
</tr>

<tr>
<td align="center">1Fh</td>
<td align="right">40000000</td>
<td>Hardware B</td>
<td align="center">M</td>
<td align="center">C</td>
<td>The tape drive has a hardware fault:
<ol>
<li>Turn the tape drive off and then on again.
<li>Restart the operation.
<li>If the problem persists, call the tape drive supplier help line.
</ol></td>
<td>The drive has a hardware fault that is not read/write related or requires a power cycle to recover.</td>
</tr>

<tr>
<td align="center">20h</td>
<td align="right">80000000</td>
<td>Interface</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive has a problem with the application client interface:
<ol>
<li>Check the cables and cable connections.
<li>Restart the operation.
</ol>
</td>
<td>The drive has identified an interface fault.</td>
</tr>

<tr>
<td align="center">21h</td>
<td align="right">100000000</td>
<td>Eject media</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The operation has failed:
<ol>
<li>Eject the tape or magazine.
<li>Insert the tape or magazine again.
<li>Restart the operation.
</ol>
</td>
<td>Error recovery action.</td>
</tr>

<tr>
<td align="center">22h</td>
<td align="right">200000000</td>
<td>Download fail</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The firmware download has failed because you have
tried to use the incorrect firmware for this tape drive.
Obtain the correct firmware and try again.</td>
<td>Firmware download failed.</td>
</tr>

<tr>
<td align="center">23h</td>
<td align="right">400000000</td>
<td>Drive humidity</td>
<td align="center">O</td>
<td align="center">W</td>
<td>Environmental conditions inside the tape drive are
outside the specified humidity range.</td>
<td>Drive humidity limits exceeded.</td>
</tr>

<tr>
<td align="center">24h</td>
<td align="right">800000000</td>
<td>Drive temperature</td>
<td align="center">O</td>
<td align="center">W</td>
<td>Environmental conditions inside the tape drive are
outside the specified temperature range.</td>
<td>Cooling problem.</td>
</tr>

<tr>
<td align="center">25h</td>
<td align="right">1000000000</td>
<td>Drive voltage</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The voltage supply to the tape drive is outside the specified range.</td>
<td>Drive voltage limits exceeded.</td>
</tr>

<tr>
<td align="center">26h</td>
<td align="right">2000000000</td>
<td>Predictive failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>A hardware failure of the tape drive is predicted. Call the tape drive supplier help line.</td>
<td>Predictive failure of drive hardware.</td>
</tr>

<tr>
<td align="center">27h</td>
<td align="right">4000000000</td>
<td>Diagnostics required</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive may have a hardware fault. Run
extended diagnostics to verify and diagnose the
problem. Check the tape drive users manual for
device specific instructions on running extended
diagnostic tests.</td>
<td>The drive may have a hardware fault that may be identified by
extended diagnostics (i.e., SEND DIAGNOSTIC command).</td>
</tr>

<tr>
<td align="center">28h - 2Eh</td>
<td>Obsolete</td>
</tr>

<tr>
<td align="center">2Fh - 31h</td>
<td>Rsvd</td>
</tr>

<tr>
<td align="center">32h</td>
<td align="right">4000000000000</td>
<td>Lost statistics
<td align="center">O</td>
<td align="center">W</td>
<td>Media statistics have been lost at some time in the past.</td>
<td>Drive or library powered on with tape loaded.</td>
</tr>

<tr>
<td align="center">33h</td>
<td align="right">8000000000000</td>
<td>Tape directory invalid at unload</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape directory on the tape cartridge just unloaded
has been corrupted. File search performance will be
degraded. The tape directory can be rebuilt by reading
all the data. </td>
<td>Error preventing the tape directory being updated on unload.</td>
</tr>

<tr>
<td align="center">34h</td>
<td align="right">10000000000000</td>
<td>Tape system area write failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The tape just unloaded could not write its system
area successfully:
<ol>
<li>Copy data to another tape cartridge.
<li>Discard the old cartridge.
</ol>
</td>
<td>Write errors while writing the system area on unload.</td>
</tr>

<tr>
<td align="center">35h</td>
<td align="right">20000000000000</td>
<td>Tape system area read failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The tape system area could not be read successfully
at load time:
<ol>
<li>Copy data to another tape cartridge.</td>
</ol>
<td>Read errors while reading the system area on load.</td>
</tr>

<tr>
<td align="center">36h</td>
<td align="right">40000000000000</td>
<td>No start of data</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The start of data could not be found on the tape:
1. Check that you are using the correct format tape.
2. Discard the tape or return the tape to your supplier.
</td>
<td>Tape damaged, bulk erased, or incorrect format.</td>
</tr>

<tr>
<td align="center">37h</td>
<td align="right">80000000000000</td>
<td>Loading failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The operation has failed because the media cannot be loaded and threaded.
<ol>
<li>Remove the cartridge, inspect it as specified in the
product manual, and retry the operation.
<li>If the problem persists, call the tape drive supplier help line.
</ol>
</td>
<td>The drive is unable to load the media and thread the tape.</td>
</tr>

<tr>
<td align="center">38h</td>
<td align="right">100000000000000</td>
<td>Unrecoverable unload failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The operation has failed because the medium cannot be unloaded:
<ol>
<li>Do not attempt to extract the tape cartridge.
<li>Call the tape driver supplier help line.
</ol>
</td>
<td>The drive is unable to unload the medium.</td>
</tr>

<tr>
<td align="center">39h</td>
<td align="right">200000000000000</td>
<td>Automation interface failure</td>
<td align="center">O</td>
<td align="center">C</td>
<td>The tape drive has a problem with the automation interface:
<ol>
<li>Check the power to the automation system.
<li>Check the cables and cable connections.
<li>Call the supplier help line if problem persists.
</ol>
</td>
<td>The drive has identified an interface fault.</td>
</tr>

<tr>
<td align="center">3Ah</td>
<td align="right">400000000000000</td>
<td>Firmware failure</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive has reset itself due to a detected firmware
fault. If problem persists, call the supplier help line.</td>
<td>Firmware bug.</td>
</tr>

<tr>
<td align="center">3Bh</td>
<td align="right">800000000000000</td>
<td>WORM Medium - Integrity Check Failed</td>
<td align="center">O</td>
<td align="center">W</td>
<td>The tape drive has detected an inconsistency during
the WORM medium integrity checks. Someone may
have tampered with the cartridge.  </td>
<td>Someone has tampered with the WORM medium.</td>
</tr>

<tr>
<td align="center">3Ch</td>
<td align="right">1000000000000000</td>
<td>WORM Medium - Overwrite Attempted</td>
<td align="center">O</td>
<td align="center">W</td>
<td>An attempt had been made to overwrite user data on a WORM medium:
<ol>
<li>If a WORM medium was used inadvertently, replace
it with a normal data medium.
<li>If a WORM medium was used intentionally:<br>
a) Check that the software application is compatible
with the WORM medium format you are using.<br>
b) Check that the medium is bar-coded correctly for WORM.
<ol>
</td>
<td>The application software does not recognize the medium as WORM.</td>
</tr>

<tr>
<td align="center">3Dh</td>
<td>Rsvd</td>
</tr>
<tr>
<td align="center">3Eh</td>
<td>Rsvd</td>
</tr>
<tr>
<td align="center">3Fh</td>
<td>Rsvd</td>
</tr>
<tr>
<td align="center">40h</td>
<td>Rsvd</td>
</tr>

</table>

<a NAME="vtl-download"></a>
<hr width="80%">
<h3>Download</h3>

<p>
Just the user-mode utilities packaged as an RPM:
<a href=http://sites.google.com/site/linuxvtl2/mhvtl-0.15-0.i686.rpm>vtl-0.15-0.i686.rpm
</a> (~50Kbytes)</p>
<p>Source code for user-mode utilities + kernel module:
<a href=http://sites.google.com/site/linuxvtl2/mhvtl-0.15-0.src.rpm>vtl-0.15-0.src.rpm
</a> (~100Kbytes)
</p>

<hr width="80%">

<p align="center">
Please email 
<a href=mailto:markh794@gmail.com>Mark Harvey</a>
any questions and/or corrections.
</p>
<p align="center">
$Id: index.html,v 1.9.2.1 2008-03-06 07:28:54 markh Exp $
</p>
</html>


================================================
FILE: etc/.gitignore
================================================
mhvtl.conf
device.conf
library_contents.10
library_contents.30
vtllibrary@.service
vtltape@.service
mhvtl-load-modules.service
generate_device_conf
generate_library_contents


================================================
FILE: etc/Makefile
================================================
#
# etc/Makefile
#

CURDIR = "../"
include ../config.mk

MHVTL_CONF_FILE = mhvtl.conf
DEVICE_CONF_FILE = device.conf
LIB_CONTENTS_FILES = library_contents.10 library_contents.30
CONFIGS = $(MHVTL_CONF_FILE) $(DEVICE_CONF_FILE) $(LIB_CONTENTS_FILES)

GENERATE_DEVICE_CONF = generate_device_conf
GENERATE_LIB_CONTENTS = generate_library_contents
GENERATORS = $(GENERATE_DEVICE_CONF) $(GENERATE_LIB_CONTENTS)

SERVICES = $(patsubst %.in,%,$(wildcard *.service*))
MHVTL_TARGET = mhvtl.target


all: $(SERVICES) $(CONFIGS)

%: %.in
	sed -e s'/@CONF_PATH@/$(CONFIG_PATH)/' \
	    -e s'/@HOME_PATH@/$(HOME_PATH)/' $< > $@

$(GENERATE_DEVICE_CONF): $(GENERATE_DEVICE_CONF).in
	sed -e s'/@CONF_PATH@/$(CONFIG_PATH)/' \
	    -e s'/@HOME_PATH@/$(HOME_PATH)/' $< > $@
	chmod 755 $@

$(GENERATE_LIB_CONTENTS): $(GENERATE_LIB_CONTENTS).in
	sed -e s'/@CONF_PATH@/$(CONFIG_PATH)/' \
	    -e s'/@HOME_PATH@/$(HOME_PATH)/' $< > $@
	chmod 755 $@

$(DEVICE_CONF_FILE): $(GENERATE_DEVICE_CONF)
	bash ./$(GENERATE_DEVICE_CONF) --force --home-dir=$(MHVTL_HOME_PATH) --override-home

$(LIB_CONTENTS_FILES): $(GENERATE_LIB_CONTENTS) $(DEVICE_CONF_FILE)
	bash ./$(GENERATE_LIB_CONTENTS) --force --config=.

.PHONY: distclean
distclean: clean

.PHONY: clean
clean:
	$(RM) $(GENERATED_FILES)
	$(RM) $(DEVICE_CONF_FILE) $(LIB_CONTENTS_FILES)

$(DESTDIR)$(SYSTEMD_SERVICE_DIR):
	install -d -m 755 $@
$(DESTDIR)$(MHVTL_CONFIG_PATH):
	install -d -m 755 $@

# Installing services
$(DESTDIR)$(SYSTEMD_SERVICE_DIR)/%.service: %.service | $(DESTDIR)$(SYSTEMD_SERVICE_DIR)
	install -m 644 $< $@
	semanage fcontext -a -t systemd_unit_file_t \'$@\'
$(DESTDIR)$(SYSTEMD_SERVICE_DIR)/%.target: %.target | $(DESTDIR)$(SYSTEMD_SERVICE_DIR)
	install -m 644 $< $@
	semanage fcontext -a -t systemd_unit_file_t \'$@\'
# Installing generator of config files
$(DESTDIR)/usr/bin/generate_%: generate_%
	install -m 755 $< $@
# save backup copies of config files
$(DESTDIR)$(MHVTL_CONFIG_PATH)/%: % | $(DESTDIR)$(MHVTL_CONFIG_PATH)
	install -m 644 -b -S .orig $< $@

.PHONY: install
install: all \
		 $(addprefix $(DESTDIR)$(SYSTEMD_SERVICE_DIR)/,$(SERVICES) $(MHVTL_TARGET)) \
		 $(addprefix $(DESTDIR)$(MHVTL_CONFIG_PATH)/,$(CONFIGS)) \
		 $(addprefix $(DESTDIR)/usr/bin/,$(GENERATORS))
	restorecon -R -v  $(DESTDIR)$(SYSTEMD_SERVICE_DIR)


================================================
FILE: etc/generate_device_conf.in
================================================
#!/bin/bash
#
# generate_device_conf -- generate device.conf output to stdout
#
#	This script generates the device.conf file,
#	and is used at installation time. This is done so that
#	administrators/users can modify or copy this script and
#	change their tape device configuration.
#

DEVICE_CONF='device.conf'
PROG_NAME="$0"
MHVTL_HOME_PATH=@HOME_PATH@
DEST_DIR='.'
FORCE=''
OVERRIDE=''

usage()
{
	echo "Usage: $PROG_NAME: [OPTIONS] -- generate a $DEVICE_CONF file"
	echo "where OPTIONS are from:"
	echo "  [-h|--help]         -- print this message and exit"
	echo "  [-H|--home-dir MHVTL_HOME_PATH]"
	echo "                      -- home path [default $MHVTL_HOME_PATH]"
	echo "  [-D|--dest-dir DIR] -- destination dir [default $DEST_DIR]"
	echo "  [-f|--force]        -- overwrite files if present"
	echo "  [-o|--override-home] -- override requirement that home dir exists"
	echo ""
	echo "To create a new $DEVICE_CONF file, edit this script and run it again"
}

#
# generate the static comments at the start of the file
#
generate_static_comments()
{
	if (( $# != 0 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	cat << CONF_START

VERSION: 5

# VPD page format:
# <page #> <Length> <x> <x+1>... <x+n>
# NAA format is an 8 hex byte value seperated by ':'
# Note: NAA is part of inquiry VPD 0x83
#
# Each 'record' is separated by one (or more) blank lines.
# Each 'record' starts at column 1
# Serial num max len is 10.
# Compression: factor X enabled 0|1
#     Where X is zlib compression factor	1 = Fastest compression
#						9 = Best compression
#     enabled 0 == off, 1 == on
#
# fifo: /var/tmp/mhvtl
# If enabled, data must be read from fifo, otherwise daemon will block
# trying to write.
# e.g. cat /var/tmp/mhvtl (in another terminal)

CONF_START
}

# add_library(DevID, Channel, Target, Lun, Vend, Prod, ProdRev, S/No)
add_library()
{
	if (( $# != 8 )) ; then
		echo "internal error: expected 8 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	VENDOR_ID="$5"
	PROD_ID="$6"
	UNIT_SN="$8"

	printf "Library: %02d CHANNEL: %02d TARGET: %02d LUN: %02d\n" \
			$ID $CH $TARGET $LUN
	echo " Vendor identification: $VENDOR_ID"
	echo " Product identification: $PROD_ID"
	echo " Unit serial number: $UNIT_SN"
	printf " NAA: %02d:22:33:44:ab:%02d:%02d:%02d\n" \
			$ID $CH $TARGET $LUN
	echo " Home directory: $MHVTL_HOME_PATH"
	echo " PERSIST: False"
	echo " Backoff: 400"
	echo "# fifo: /var/tmp/mhvtl"
	echo ""
}

# add_drive(DevID, Channel, Target, Lun, Vend, Prod, ProdRev, S/No, LibID, Slot, Density)
add_drive()
{
	if (( $# != 11 )) ; then
		echo "internal error: expected 11 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	VENDORID=$5
	PRODUCTID=$6
	PRODUCTREV=$7
	UNITSERNO=$8
	LIB=$9

	# get arg 10 & 11
	shift 9
	SLOT=$1
	DENSITY=$2

	printf "Drive: %02d CHANNEL: %02d TARGET: %02d LUN: %02d\n" \
			$ID $CH $TARGET $LUN
	printf " Library ID: %02d Slot: %02d\n" \
			$LIB $SLOT
	echo " Vendor identification: $VENDORID"
	echo " Product identification: $PRODUCTID"
	echo " Product revision level: $PRODUCTREV"
	echo " Unit serial number: $UNITSERNO"
	printf " NAA: %02d:22:33:44:ab:%02d:%02d:%02d\n" \
			$LIB $CH $TARGET $LUN
	echo " Compression: factor 1 enabled 1"
	echo " Compression type: lzo"
	echo " Backoff: 400"
	echo "# fifo: /var/tmp/mhvtl"
	echo ""
}

# add_ibm_ultrium_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD1"
	PRODUCTREV="550V"
	DENSITY="42"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_2_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_2_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD2"
	PRODUCTREV="550V"
	DENSITY="44"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_3_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_3_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD3"
	PRODUCTREV="550V"
	DENSITY="46"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_4_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_4_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD4"
	PRODUCTREV="550V"
	DENSITY="48"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_5_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_5_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD5"
	PRODUCTREV="550V"
	DENSITY="50"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_6_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_6_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD6"
	#### According to IBM LTO SCSI reference: REV is built of
	 # "ABCD" - so 2160 decodes as Year 2022 (2), Jan (1), Day (6th), Version '0'
	 # A = last digit char of year
	 # B = Month, 1 - 9, A, B, C
	 # C = Day, 1-9, A-V
	 # D = Version
	PRODUCTREV="2160"
	DENSITY="50"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_7_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_7_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD7"
	#### According to IBM LTO SCSI reference: REV is built of
	 # "ABCD" - so 2160 decodes as Year 2022 (2), Jan (1), Day (6th), Version '0'
	 # A = last digit char of year
	 # B = Month, 1 - 9, A, B, C
	 # C = Day, 1-9, A-V
	 # D = Version
	PRODUCTREV="2160"
	DENSITY="50"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_ibm_ultrium_8_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_ibm_ultrium_8_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="IBM"
	PRODUCTID="ULT3580-TD8"
	#### According to IBM LTO SCSI reference: REV is built of
	 # "ABCD" - so 2160 decodes as Year 2022 (2), Jan (1), Day (6th), Version '0'
	 # A = last digit char of year
	 # B = Month, 1 - 9, A, B, C
	 # C = Day, 1-9, A-V
	 # D = Version
	PRODUCTREV="2160"
	DENSITY="50"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_stk_t10kb_drive(DevID, Channel, Target, Lun, S/No, LibID, Slot)
add_stk_t10kb_drive()
{
	if (( $# != 7 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi
	ID=$1
	CH=$2
	TARGET=$3
	LUN=$4
	UNITSERNO=$5
	LIB=$6
	SLOT=$7
	VENDORID="STK"
	PRODUCTID="T10000B"
	PRODUCTREV="550V"
	DENSITY="50"

	add_drive $ID $CH $TARGET $LUN $VENDORID $PRODUCTID $PRODUCTREV $UNITSERNO $LIB $SLOT $DENSITY
}

# add_library_contents_10(void) -- add the robot "10" with 4 drives
add_library_contents_10()
{
	if (( $# != 0 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi

	#         index channel target LUN Vendor ProdID ProdRev S/No
	add_library 10 0 0 0 "STK" "L700"  "550V"  "XYZZY_A"
	#         index channel target LUN S/No Lib# Slot
	add_ibm_ultrium_8_drive 11 0 1 0 "XYZZY_A1" 10 1
	add_ibm_ultrium_8_drive 12 0 2 0 "XYZZY_A2" 10 2
	add_ibm_ultrium_6_drive 13 0 3 0 "XYZZY_A3" 10 3
	add_ibm_ultrium_6_drive 14 0 4 0 "XYZZY_A4" 10 4
}

# add_library_contents_30(void) -- add the robot "30" with 4 drives
add_library_contents_30()
{
	if (( $# != 0 )) ; then
		echo "internal error: expected 0 arguments, got $#" 1>&2
		exit 1
	fi

	#         index channel target LUN Vendor ProdID ProdRev S/No
	add_library 30 0 8 0 "STK" "L80"  "550V"  "XYZZY_B"
	#         index channel target LUN S/No Lib# Slot
	add_stk_t10kb_drive 31 0 9 0 "XYZZY_B1" 30 1
	add_stk_t10kb_drive 32 0 10 0 "XYZZY_B2" 30 2
	add_stk_t10kb_drive 33 0 11 0 "XYZZY_B3" 30 3
	add_stk_t10kb_drive 34 0 12 0 "XYZZY_B4" 30 4
}

#
# start of script
#

TEMP=$(getopt -o 'hH:D:fo' --long 'help,home-dir:,dest-dir:,force,override-home' -n "$PROG_NAME" -- "$@")
if [[ $? -ne 0 ]] ; then
	usage
	exit 1
fi
eval set - "$TEMP"
unset TEMP

while true; do
	case "$1" in
	'-h'|'--help')
		usage
		exit 0
		;;
	'-H'|'--home-dir')
		MHVTL_HOME_PATH="$2"
		shift 2
		continue
		;;
	'-D'|'--dest-dir')
		DEST_DIR="$2"
		shift 2
		continue
		;;
	'-f'|'--force')
		FORCE='1'
		shift
		continue
		;;
	'-o'|'--override-home')
		OVERRIDE='1'
		shift
		continue
		;;
	'--')
		shift
		break
		;;
	*)
		echo "internal error: unknown arg: $1" 1>&2
		exit 1
	esac
done

# should be no more arguments
if [[ $# -gt 0 ]] ; then
	echo "error: too many arguments"
	usage
	exit 1
fi

# verify a home path make sense
# (for use in the device.conf we generate)
if [[ ! -d "$MHVTL_HOME_PATH" ]] ; then
	if [[ -z "$OVERRIDE" ]] ; then
		echo "error: $MHVTL_HOME_PATH not a directory" 1>&2
		usage
		exit 1
	fi
fi

# ensure we do not step on earlier config file
if [[ -r $DEST_DIR/$DEVICE_CONF ]] ; then
	if [[ -z "$FORCE" ]] ; then
		echo "error: already exists: $DEST_DIR/$DEVICE_CONF" 1>&2
		exit 1
	fi
fi

echo '===>' "Generating: $DEST_DIR/$DEVICE_CONF ..."
(
	generate_static_comments
	add_library_contents_10
	add_library_contents_30
) > $DEST_DIR/$DEVICE_CONF


================================================
FILE: etc/generate_library_contents.in
================================================
#!/bin/bash
#
# generate_library_contents -- generate library_contents.* files
#
#	This script generates the library_contents.<NUMBER> (where
#	number defaults to 10 and 30) files in our configuration
#	directory. This is normally only done at installation time,
#	but having this script makes it possible for administrators/
#	users to customize the configuration if desired.
#

DEVICE_CONF='device.conf'
PROG_NAME="$0"
FORCE=''
MHVTL_CONFIG_PATH='@CONF_PATH@'
DEST_DIR='.'

usage()
{
	echo "Usage: $PROG_NAME: [OPTIONS] -- generate" 'library_contents.*' "files from $DEVICE_CONF"
	echo "where OPTIONS are from:"
	echo "  [-h|--help]                   -- print this message and exit"
	echo "  [-C|--config-dir CONFIG_DIR]  -- specificy config dir [default $MHVTL_CONFIG_PATH]"
	echo "  [-D|--dest-dir DIRECTORY]     -- specificy destination dir [default $DEST_DIR]"
	echo "  [-f|--force]                  -- overwrite files if present"
}

create_library_file()
{
	if (( $# != 1 )) ; then
		echo "create_library_file internal error: expected 1 argument, got $#" 1>&2
		exit 1
	fi

	LIBID=$1

	echo "VERSION: 2"
	echo ""

	# Count number of drives in this library
	DRV_COUNT=$(grep -c "Library ID: $LIBID" $MHVTL_CONFIG_PATH/$DEVICE_CONF)

	# Add a 'Drive X:' for each drive
	for a in $(seq 1 $DRV_COUNT) ; do
		printf "Drive %d:\n" $a
	done

	# create the static (non-changing, comment) part of the file
	cat <<CONF_SAMPLE

Picker 1:

MAP 1:
MAP 2:
MAP 3:
MAP 4:

# Slot 1 - ?, no gaps
# Slot N: [barcode]
# [barcode]
# a barcode is comprised of three fields: [Leading] [identifier] [Trailing]
# Leading "CLN" -- cleaning tape
# Leading "W" -- WORM tape
# Leading "NOBAR" -- will appear to have no barcode
# If the barcode is at least 8 character long, then the last two characters are Trailing
# Trailing "S3" - SDLT600
# Trailing "X4" - AIT-4
# Trailing "L1" - LTO 1, "L2" - LTO 2, "L3" - LTO 3, "L4" - LTO 4, "L5" - LTO 5
# Trailing "LT" - LTO 3 WORM, "LU" -  LTO 4 WORM, "LV" - LTO 5 WORM
# Trailing "L6" - LTO 6, "LW" - LTO 6 WORM
# Trailing "TA" - T10000+
# Trailing "TZ" - 9840A, "TY" - 9840B, "TX" - 9840C, "TW" - 9840D
# Trailing "TV" - 9940A, "TU" - 9940B
# Trailing "JA" - 3592+
# Trailing "JB" - 3592E05+
# Trailing "JC" - 3592E06+
# Trailing "JK" - 3592E07+
# Trailing "JW" - WORM 3592+
# Trailing "JX" - WORM 3592E05+ & 3592E06
# Trailing "JY" - WORM 3592E07+
# Trailing "D7" - DLT7000 media (DLT IV)
#
CONF_SAMPLE

	# create the data in the file
	case $LIBID in
	'10')
		# LTO-8 Media
		for a in {1..20} ; do
			printf "Slot $a: E0%02d%02dL8\n" $LIBID $a
		done
		printf "Slot 21: \n"
		printf "Slot 22: CLN%02d1L8\n" $LIBID
		printf "Slot 23: CLN%02d2L6\n" $LIBID
		for a in {24..29} ; do
			printf "Slot $a:\n"
		done

		# LTO-6 Media
		for a in {30..39} ; do
			printf "Slot $a: F0%02d%02dL6\n" $LIBID $a
		done
		;;

	'30')
		for a in {1..39} ; do
			printf "Slot $a: G0%02d%02dTA\n" $LIBID $a
		done
		printf "Slot 40: CLN%02d3TA\n" $LIBID
		;;

	*)
		# Not a library this script created, but create some slots anyway
		for a in {1..39} ; do
			printf "Slot $a: M0%02d%02d\n" $LIBID $a
		done
		;;
	esac
}

#
# start of script
#

TEMP=$(getopt -o 'hC:D:f' --long 'help,config-dir:,dest-dir:,force' -n "$PROG_NAME" -- "$@")
if [[ $? -ne 0 ]] ; then
	usage
	exit 1
fi
eval set - "$TEMP"
unset TEMP

while true; do
	case "$1" in
	'-h'|'--help')
		usage
		exit 0
		;;
	'-C'|'--config-dir')
		MHVTL_CONFIG_PATH="$2"
		shift 2
		continue
		;;
	'-D'|'--dest-dir')
		DEST_DIR="$2"
		shift 2
		continue
		;;
	'-f'|'--force')
		FORCE='1'
		shift
		continue
		;;
	'--')
		shift
		break
		;;
	*)
		echo "internal error: unknown arg: $1" 1>&2
		exit 1
	esac
done

# should be no more arguments
if [[ $# -gt 0 ]] ; then
	echo "error: too many arguments" 1>&2
	usage
	exit 1
fi

if [[ ! -d $MHVTL_CONFIG_PATH ]] ; then
	echo "error: mhvtl config path not present: $MHVTL_CONFIG_PATH" 1>&2
	usage
	exit 1
fi
if [[ ! -r $MHVTL_CONFIG_PATH/$DEVICE_CONF ]] ; then
	echo "error: need device config file: $MHVTL_CONFIG_PATH/$DEVICE_CONF" 1>&2
	usage
	exit 1
fi

# get a list of our libraries
LIB_ID_LIST=$(awk '/^Library:/ {print $2}' $MHVTL_CONFIG_PATH/$DEVICE_CONF)

for id in $LIB_ID_LIST ; do
	ID_FILE="$DEST_DIR/library_contents.$id"

	if [[ -r $ID_FILE ]] ; then
		if [[ -z "$FORCE" ]] ; then
			echo "error: already exists: $ID_FILE" 1>&2
			exit 1
		fi
	fi
	echo '===>' "Generating: $ID_FILE ..."
	create_library_file $id > $ID_FILE
done

exit 0


================================================
FILE: etc/library_contents.sample
================================================
# Define how many tape drives you want in the vtl..

Drive 1:
Drive 2:
Drive 3:
Drive 4:
Drive 5:
Drive 6:
Drive 7:
Drive 8:

# Place holder for the robotic arm. Not really used.
Picker 1:

# Media Access Port
# (mailslots, Cartridge Access Port, <insert your favourate name here>)
# Again, define how many MAPs this vtl will contain.
MAP 1:
MAP 2:
MAP 3:
MAP 4:

# And the 'big' on, define your media and in which slot contains media.
# When the rc script is started, all media listed here will be created
# using the default media capacity.
Slot 1:	ULT001L1
Slot 2: ULT002L1
Slot 3: ULT003L1
Slot 4: ULT004L1
Slot 5: ULT005L1
Slot 6: ULT006L1
Slot 7: ULT007L1
Slot 8: ULT008L1
Slot 9: ULT009L1
Slot 10: ULT010L1
Slot 11: SDLT01L1
Slot 12: SDLT02L1
Slot 13: SDLT03L1
Slot 14: SDLT04L1
Slot 15: SDLT05L1
Slot 16: SDLT06L1
Slot 17: SDLT07L1
Slot 18: SDLT08L1
Slot 19: SDLT09L1
Slot 20: SDLT10L1
Slot 21:
Slot 22:
Slot 23:
Slot 24:
Slot 25:
Slot 26:
Slot 27:
Slot 28:
Slot 29:
Slot 30:
Slot 31: CLN001L1
Slot 32: CLN002L1


================================================
FILE: etc/mhvtl-load-modules.service.in
================================================
[Unit]
Description=Load mhvtl modules
Documentation=man:man:vtltape(1) man:man:vtllibrary(1)
Before=mhvtl.target
PartOf=mhvtl.target
Conflicts=shutdown.target
Before=shutdown.target

[Service]
Type=oneshot
RemainAfterExit=yes
Environment=VTL_DEBUG="0"
EnvironmentFile=-@CONF_PATH@/mhvtl.conf
ExecStart=/sbin/modprobe mhvtl opts=${VTL_DEBUG}
ExecStart=/sbin/modprobe sg

[Install]
WantedBy=mhvtl.target


================================================
FILE: etc/mhvtl.conf.in
================================================
#
# mhvtl.conf
#

# Home directory for tape emulation files
MHVTL_HOME_PATH=@HOME_PATH@

# Default media capacity (500 M)
CAPACITY=500

# Set default verbosity [0|1|2|3]
VERBOSE=1

# Set kernel module debugging [0|1]
VTL_DEBUG=0

# vtltape and vtllibrary debugging [Blank or -d]
#DAEMON_DEBUG=-d


================================================
FILE: etc/mhvtl.target
================================================
[Unit]
Description=mhvtl service allowing to start/stop all vtltape@.service and vtllibrary@.service instances at once
Documentation=man:man:vtltape(1) man:man:vtllibrary(1)

[Install]
WantedBy=multi-user.target


================================================
FILE: etc/vtllibrary@.service.in
================================================
[Unit]
Documentation=man:vtllibrary(1) man:vtlcmd(1)
Description=Robot Library Daemon for Virtual Tape & Robot Library
Before=mhvtl.target
Requires=mhvtl-load-modules.service
After=mhvtl-load-modules.service
PartOf=mhvtl.target

[Service]
Type=simple
Environment=VERBOSE=0
Environment=DAEMON_DEBUG=
EnvironmentFile=-@CONF_PATH@/mhvtl.conf
ExecStart=/usr/bin/vtllibrary -F -q%i -v${VERBOSE} ${DAEMON_DEBUG}
ExecStop=/usr/bin/vtlcmd %i exit
KillMode=none
ExecReload=/usr/bin/kill -HUP $MAINPID

[Install]
WantedBy=mhvtl.target


================================================
FILE: etc/vtltape@.service.in
================================================
[Unit]
Documentation=man:vtltape(1) man:vtlcmd(1)
Description=Tape Daemon for Virtual Tape & Robot Library
Before=mhvtl.target
Requires=mhvtl-load-modules.service
After=mhvtl-load-modules.service
PartOf=mhvtl.target

[Service]
Type=simple
Environment=VERBOSE=0
Environment=DAEMON_DEBUG=
EnvironmentFile=-@CONF_PATH@/mhvtl.conf
ExecStart=/usr/bin/vtltape -F -q%i -v${VERBOSE} ${DAEMON_DEBUG}
ExecStop=/usr/bin/vtlcmd %i exit
KillMode=none

[Install]
WantedBy=mhvtl.target


================================================
FILE: include/common/logging.h
================================================
/*
 * logging macros
 *
 * Copyright (C) 2005-2025 Mark Harvey markh794@gmail.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#ifndef _LOGGING_H_
#define _LOGGING_H_

#include <syslog.h>
#include <stdint.h>

#define MHVTL_OPT_NOISE 0x11

#ifdef MHVTL_DEBUG
extern char	   mhvtl_driver_name[];
extern uint8_t debug;
extern uint8_t verbose;

#define MHVTL_DBG_NO_FUNC(lvl, format, arg...)            \
	do {                                                  \
		if (debug)                                        \
			printf("%s: " format "\n",                    \
				   mhvtl_driver_name, ##arg);             \
		else if ((verbose) >= (lvl))                      \
			syslog(LOG_DAEMON | LOG_INFO, format, ##arg); \
	} while (0)

#define MHVTL_ERR(format, arg...)                                         \
	do {                                                                  \
		if (debug) {                                                      \
			printf("%s: ERROR: %s(): " format "\n",                       \
				   mhvtl_driver_name, __func__, ##arg);                   \
			fflush(NULL);                                                 \
		} else {                                                          \
			syslog(LOG_DAEMON | LOG_ERR, "ERROR: %s(): line: %d," format, \
				   __func__, __LINE__, ##arg);                            \
		}                                                                 \
	} while (0)

#define MHVTL_LOG(format, arg...)                         \
	do {                                                  \
		if (debug) {                                      \
			printf("%s: %s(): " format "\n",              \
				   mhvtl_driver_name, __func__, ##arg);   \
			fflush(NULL);                                 \
		} else {                                          \
			syslog(LOG_DAEMON | LOG_ERR, "%s(): " format, \
				   __func__, ##arg);                      \
		}                                                 \
	} while (0)

#define MHVTL_DBG(lvl, format, arg...)                     \
	do {                                                   \
		if (debug)                                         \
			printf("%s: %s(): " format "\n",               \
				   mhvtl_driver_name, __func__, ##arg);    \
		else if ((verbose) >= (lvl))                       \
			syslog(LOG_DAEMON | LOG_INFO, "%s(): " format, \
				   __func__, ##arg);                       \
	} while (0)

#define MHVTL_DBG_PRT_CDB(lvl, cmd)      \
	do {                                 \
		if (debug) {                     \
			mhvtl_prt_cdb((lvl), (cmd)); \
		} else if ((verbose) >= (lvl)) { \
			mhvtl_prt_cdb((lvl), (cmd)); \
		}                                \
	} while (0)

#else

#define MHVTL_DBG(lvl, s...)
#define MHVTL_DBG_NO_FUNC(lvl, s...)
#define MHVTL_DBG_PRT_CDB(lvl, cmd)

#define MHVTL_ERR(format, arg...)                            \
	do {                                                     \
		syslog(LOG_DAEMON | LOG_ERR, "ERROR: %s(): " format, \
			   __func__, ##arg);                             \
	} while (0)

#define MHVTL_LOG(format, arg...)                     \
	do {                                              \
		syslog(LOG_DAEMON | LOG_ERR, "%s(): " format, \
			   __func__, ##arg);                      \
	} while (0)

#endif /* MHVTL_DEBUG */
#endif /*  _LOGGING_H_ */


================================================
FILE: include/common/mhvtl_scsi.h
================================================
/*
 * The userspace tape/library header file for the vtl virtual
 * tape kernel module.
 *
 * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail dot com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#ifndef _SCSI_SCSI_H
#define _SCSI_SCSI_H

/*
 * Device types
 */
#define TYPE_DISK			0x00
#define TYPE_TAPE			0x01
#define TYPE_PROCESSOR		0x03
#define TYPE_WORM			0x04
#define TYPE_ROM			0x05
#define TYPE_SCANNER		0x06
#define TYPE_MOD			0x07
#define TYPE_MEDIUM_CHANGER 0x08
#define TYPE_ENCLOSURE		0x0d
#define TYPE_NO_LUN			0x7f

/*
 * SCSI Architectual model (SAM) Status codes.
 */
#define SAM_STAT_GOOD						0x00
#define SAM_STAT_CHECK_CONDITION			0x02
#define SAM_STAT_CONDITION_MET				0x04
#define SAM_STAT_BUSY						0x08
#define SAM_STAT_INTERMEDIATE				0x10
#define SAM_STAT_INTERMEDIATE_CONDITION_MET 0x14
#define SAM_STAT_RESERVATION_CONFLICT		0x18
#define SAM_STAT_COMMAND_TERMINATED			0x22
#define SAM_STAT_QUEUE_FULL					0x28

/*
 * SENSE keys
 */
#define NO_SENSE		0x00
#define RECOVERED_ERROR 0x01
#define NOT_READY		0x02
#define MEDIUM_ERROR	0x03
#define HARDWARE_ERROR	0x04
#define ILLEGAL_REQUEST 0x05
#define UNIT_ATTENTION	0x06
#define DATA_PROTECT	0x07
#define BLANK_CHECK		0x08
#define VOLUME_OVERFLOW 0x0d

/*
 * OP Codes
 */

#define ALLOW_MEDIUM_REMOVAL				 0x1e
#define ALLOW_OVERWRITE						 0x82
#define ACCESS_CONTROL_IN					 0x86
#define ACCESS_CONTROL_OUT					 0x87
#define EXTENDED_COPY						 0x83
#define A3_SA								 0xa3
#define A4_SA								 0xa4
#define ERASE_6								 0x19
#define ERASE_16							 0x93
#define FORMAT_UNIT							 0x04
#define EXCHANGE_MEDIUM						 0xa6
#define INITIALIZE_ELEMENT_STATUS			 0x07
#define INITIALIZE_ELEMENT_STATUS_WITH_RANGE 0xE7
#define INQUIRY								 0x12
#define LOAD_DISPLAY						 0x06 /* STK T10000 specific */
#define LOCATE_10							 0x2b
#define LOCATE_16							 0x92
#define MODE_SENSE							 0x1a
#define MODE_SENSE_10						 0x5a
#define MODE_SELECT							 0x15
#define MODE_SELECT_10						 0x55
#define MOVE_MEDIUM							 0xa5
#define LOG_SELECT							 0x4c
#define LOG_SENSE							 0x4d
#define PERSISTENT_RESERVE_IN				 0x5e
#define PERSISTENT_RESERVE_OUT				 0x5f
#define READ_6								 0x08
#define READ_10								 0x28
#define READ_12								 0xa8
#define READ_16								 0x88
#define READ_ATTRIBUTE						 0x8c
#define READ_BLOCK_LIMITS					 0x05
#define READ_BUFFER							 0x3c
#define READ_ELEMENT_STATUS					 0xb8
#define READ_MEDIA_SERIAL_NUMBER			 0xab
#define READ_POSITION						 0x34
#define READ_REVERSE_6						 0x0f
#define READ_REVERSE_16						 0x81
#define RECEIVE_DIAGNOSTIC					 0x1c
#define RECOVER_BUFFERED_DATA				 0x14
#define RELEASE								 0x17
#define RELEASE_10							 0x57
#define REPORT_DENSITY						 0x44
#define REPORT_ELEMENT_INFORMATION			 0x9e
#define REPORT_LUNS							 0xa0
#define REQUEST_SENSE						 0x03
#define RESERVE								 0x16
#define RESERVE_10							 0x56
#define REZERO_UNIT							 0x01
#define SECURITY_PROTOCOL_IN				 0xa2
#define SECURITY_PROTOCOL_OUT				 0xb5
#define SEND_DIAGNOSTIC						 0x1d
#define SET_CAPACITY						 0x0b
#define SPACE								 0x11
#define SPACE_16							 0x91
#define START_STOP							 0x1b
#define TEST_UNIT_READY						 0x00
#define VERIFY_6							 0x13
#define VERIFY_16							 0x8f
#define WRITE_6								 0x0a
#define WRITE_10							 0x2a
#define WRITE_12							 0xaa
#define WRITE_16							 0x8a
#define WRITE_ATTRIBUTE						 0x8d
#define WRITE_BUFFER						 0x3b
#define WRITE_FILEMARKS						 0x10
#define WRITE_FILEMARKS_16					 0x80

/* Service codes */
#define FORCED_EJECT			 0x1f
#define MANAGEMENT_PROTOCOL_IN	 0x10
#define MANAGEMENT_PROTOCOL_OUT	 0x10
#define CHANGE_ALIASES			 0x0b
#define REPORT_ALIASES			 0x0b
#define REPORT_SUPPORTED_OPCODES 0x0c
#define REPORT_TIMESTAMP		 0x0f
#define SET_TIMESTAMP			 0x0f

/* No Sense Errors */
#define NO_ADDITIONAL_SENSE			 0x0000
#define E_MARK						 0x0001
#define E_EOM						 0x0002
#define E_BOM						 0x0004
#define E_END_OF_DATA				 0x0005
#define E_PROGRAMMABLE_EARLY_WARNING 0x0007
#define E_OP_IN_PROGRESS			 0x0016
#define E_DRIVE_REQUIRES_CLEANING	 0x8282

/* Recovered Errors */
#define E_WRITE_ERROR			 0x0c00
#define E_READ_ERROR			 0x1100
#define E_RECOVERED_WITH_RETRYS	 0x1701
#define E_MEDIA_LOAD_EJECT_ERROR 0x5300
#define E_FAILURE_PREDICTION	 0x5d00

/* Not ready */
#define E_CAUSE_NOT_REPORTABLE	  0x0400
#define E_BECOMING_READY		  0x0401
#define E_INITIALIZING_REQUIRED	  0x0402
#define E_OFFLINE				  0x0412
#define E_EARLY_WARNING_EOM		  0x2c98
#define E_CLEANING_CART_INSTALLED 0x3003
#define E_CLEANING_FAILURE		  0x3007
#define E_MEDIUM_NOT_PRESENT	  0x3a00
#define E_MAP_OPEN				  0x3a02
#define E_LOGICAL_UNIT_NOT_CONFIG 0x3e00

/* Medium Errors */
#define E_WRITE_ERROR				0x0c00
#define E_UNRECOVERED_READ			0x1100
#define E_RECORDED_ENTITY_NOT_FOUND 0x1400
#define E_UNKNOWN_FORMAT			0x3001
#define E_IMCOMPATIBLE_FORMAT		0x3002
#define E_MEDIUM_FMT_CORRUPT		0x3100
#define E_SEQUENTIAL_POSITION_ERR	0x3b00
#define E_WRITE_APPEND_ERR			0x5000
#define E_CARTRIDGE_FAULT			0x5200

/* Hardware Failure */
#define E_COMPRESSION_CHECK			 0x0c04
#define E_LOGICAL_BLOCK_GUARD_FAILED 0x1001
#define E_DECOMPRESSION_CRC			 0x110d
#define E_MANUAL_INTERVENTION_REQ	 0x0403
#define E_HARDWARE_FAILURE			 0x4000
#define E_INTERNAL_TARGET_FAILURE	 0x4400
#define E_ERASE_FAILURE				 0x5100

/* Illegal Request */
#define E_PARAMETER_LIST_LENGTH_ERR		  0x1a00
#define E_INVALID_OP_CODE				  0x2000
#define E_ILLEGAL_COMMAND_WHEN_NOT_APPEND 0x200C
#define E_INVALID_ELEMENT_ADDR			  0x2101
#define E_INVALID_FIELD_IN_CDB			  0x2400
#define E_LUN_NOT_SUPPORTED				  0x2500
#define E_INVALID_FIELD_IN_PARMS		  0x2600
#define E_MEDIUM_INCOMPATIBLE			  0x3000
#define E_SAVING_PARMS_UNSUP			  0x3900
#define E_SEQUENTIAL_POSITIONING_ERROR	  0x3b00
#define E_MEDIUM_DEST_FULL				  0x3b0d
#define E_MEDIUM_SRC_EMPTY				  0x3b0e
#define E_POSITION_PAST_BOM				  0x3b0c
#define E_MEDIUM_REMOVAL_PREVENTED		  0x5302
#define E_BAD_MICROCODE_DETECTED		  0x8283

/* Unit Attention */
#define E_NOT_READY_TO_TRANSITION  0x2800
#define E_IMPORT_ELEMENT_ACCESSED  0x2801
#define E_POWERON_RESET			   0x2900
#define E_I_T_NEXUS_LOSS		   0x2907
#define E_MODE_PARAMETERS_CHANGED  0x2a01
#define E_MICROCODE_DOWNLOADED	   0x3f01
#define E_FAILURE_PREDICTION_FALSE 0x5dff
#define E_MODE_PARAMETERS_CHANGED  0x2a01
#define E_TIMESTAMP_CHANGED		   0x2a10
#define E_INQUIRY_DATA_HAS_CHANGED 0x3f03

/* Data Protect */
#define E_WRITE_PROTECT			   0x2700
#define E_MEDIUM_OVERWRITE_ATTEMPT 0x300c
#define E_UNABLE_TO_DECRYPT		   0x7401
#define E_UNENCRYPTED_DATA		   0x7402
#define E_INCORRECT_KEY			   0x7403

/* Suppress Incorrect Length Indicator */
#define SILI 0x2
/* Fixed block format */
#define FIXED_BLOCK 0x1

/* Sense Data format bits & pieces */
/* Incorrect Length Indicator */
#define SD_CURRENT_INFORMATION_FIXED 0x70
#define SD_VALID					 0x80
#define SD_FILEMARK					 0x80
#define SD_EOM						 0x40
#define SD_ILI						 0x20

/* Sense - field pointer sense key specific data - SPC4 - 4.5.2.4 */
#define SKSV 0x80
#define CD	 0x40
#define BPV	 0x08

/* MODE PAGE */
#define MODE_RW_ERROR_RECOVER		  0x01
#define MODE_DISCONNECT_RECONNECT	  0x02
#define MODE_CONTROL				  0x0a
#define MODE_DATA_COMPRESSION		  0x0f
#define MODE_DEVICE_CONFIGURATION	  0x10
#define MODE_MEDIUM_PARTITION		  0x11
#define MODE_POWER_CONDITION		  0x1a
#define MODE_INFORMATION_EXCEPTION	  0x1c
#define MODE_MEDIUM_CONFIGURATION	  0x1d
#define MODE_ELEMENT_ADDRESS		  0x1d
#define MODE_TRANSPORT_GEOMETRY		  0x1e
#define MODE_DEVICE_CAPABILITIES	  0x1f
#define MODE_VENDOR_SPECIFIC_24H	  0x24
#define MODE_VENDOR_SPECIFIC_25H	  0x25
#define MODE_BEHAVIOR_CONFIGURATION	  0x2f
#define MODE_ENCRYPTION_MODE		  0x30
#define MODE_AIT_DEVICE_CONFIGURATION 0x31

#define TA_NONE						 0x00
#define TA_READ						 0x01
#define TA_WRITE					 0x02
#define TA_HARD						 0x04
#define TA_MEDIA					 0x08
#define TA_READ_FAILURE				 0x10
#define TA_WRITE_FAILURE			 0X20
#define TA_MEDIA_EOL				 0x40
#define TA_NOT_DATA_GRADE			 0X80
#define TA_WRITE_PROTECT			 0X100
#define TA_DRIVE_IN_USE				 0x200
#define TA_CLEANING_MEDIA			 0x400
#define TA_MEDIA_NOT_SUPPORTED		 0x800
#define TA_RECOV_CART_FAILURE		 0x1000
#define TA_UNRECOV_CART_FAILURE		 0x2000
#define TA_MEM_CHIP_FAILURE			 0x4000
#define TA_TAPE_UNMOUNTED			 0x8000
#define TA_MEDIA_RO					 0x10000
#define TA_MEDIA_DIR_CORRUPT		 0x20000
#define TA_MEDIA_NEAR_EOL			 0x40000
#define TA_DRIVE_NEEDS_CLEANING		 0x80000
#define TA_CLEAN_PERIODIC			 0x100000
#define TA_EXPIRED_CLEANING_CART	 0x200000
#define TA_INVALID_CLEANING_CART	 0x400000
#define TA_RETENTION_REQUESTED		 0x800000
#define TA_INTERFACE_PORT_ERROR		 0x1000000
#define TA_COOLING_FAN_FAILURE		 0x2000000
#define TA_PSU_FAILURE				 0x4000000
#define TA_PSU_POWER_CONSUMPTION	 0x8000000
#define TA_PREVENTIVE_MAINTENANCE	 0x10000000
#define TA_HARDWARE_A_FAULT			 0x20000000
#define TA_HARDWARE_B_FAULT			 0x40000000
#define TA_INTERFACE_FAULT			 0x80000000
#define TA_MOUNT_FAILURE			 0x100000000ull
#define TA_INCORRECT_FIRMWARE		 0x200000000ull
#define TA_HUMIDITY_CONDITIONS		 0x400000000ull
#define TA_TEMPERATURE_CONDITIONS	 0x800000000ull
#define TA_DRIVE_VOLTAGE			 0x1000000000ull
#define TA_PREDICTIVE_FAILURE		 0x2000000000ull
#define TA_DIAGNOSTICS_REQUIRED		 0x4000000000ull
#define TA_LOST_STATISTICS			 0x2000000000000ull
#define TA_TAPE_DIR_INVALID			 0x4000000000000ull
#define TA_SYSTEM_AREA_WRITE_FAILURE 0x8000000000000ull
#define TA_SYSTEM_AREA_READ_FAILURE	 0x10000000000000ull
#define TA_NO_START_OF_DATA			 0x20000000000000ull
#define TA_LOAD_FAILURE				 0x40000000000000ull
#define TA_UNRECOV_UNLOAD_FAILURE	 0x80000000000000ull
#define TA_AUTOMATION_FAILURE		 0x100000000000000ull
#define TA_FIRMWARE_FAILURE			 0x200000000000000ull
#define TA_WORM_INTEGRITY_FAILED	 0x400000000000000ull
#define TA_WORM_OVERWRITE_ATTEMPTED	 0x800000000000000ull

#endif /* _SCSI_SCSI_H */

================================================
FILE: include/common/vtl_common.h
================================================
/* Common stuff for kernel and usr programs */
#ifndef VTL_COMMON_H
#define VTL_COMMON_H

#define SENSE_BUF_SIZE 96
/* Max cdb size */
#define MAX_COMMAND_SIZE 16

#define VTL_IDLE	  0x00
#define VTL_QUEUE_CMD 0xfe

/* ioctl defines */
#define VX_TAPE_ONLINE			0x80
#define VTL_POLL_AND_GET_HEADER 0x200
#define VTL_GET_DATA			0x201
#define VTL_PUT_DATA			0x203
#define VTL_REMOVE_LU			0x205

#define VENDOR_ID_LEN	8
#define PRODUCT_ID_LEN	16
#define PRODUCT_REV_LEN 4

struct mhvtl_header {
	unsigned long long serialNo;
	unsigned char	   cdb[MAX_COMMAND_SIZE];
	unsigned char	  *buf;
};

struct mhvtl_ds {
	void			  *data;
	unsigned int	   sz;
	unsigned long long serialNo;
	void			  *sense_buf;
	unsigned char	   sam_stat;
};

struct mhvtl_ctl {
	unsigned int channel;
	unsigned int id;
	unsigned int lun;
};

#if !defined(FALSE)
#define FALSE 0
#endif

#if !defined(TRUE)
#define TRUE 1
#endif

#endif /* VTL_COMMON_H */


================================================
FILE: include/common/vtl_u.h
================================================
/*
 * vtl_u.h
 */
#define NETLINK_VTL 22

struct mhvtl_event {
	u32			tid;
	aligned_u64 sid;
	aligned_u64 serial_no;
	u32			cid;
	u32			state;
}


================================================
FILE: include/common/vtltape_pem.h
================================================
static char *certificate =
	"-----BEGIN CERTIFICATE-----\n"
	"MIID9zCCA2CgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBhMCTlox\n"
	"EzARBgNVBAcTCldlbGxpbmd0b24xPDA6BgNVBAoTM1JlYWxseSBJcnJlc3BvbnNp\n"
	"YmxlIEF1dGhvcmlzYXRpb24gQXV0aG9yaXR5IChSSUFBKTEWMBQGA1UECxMNQ2Vy\n"
	"dC1zdGFtcGluZzEZMBcGA1UEAxMQSmFja292IGFsLVRyYWRlczEfMB0GCSqGSIb3\n"
	"DQEJARYQbm9uZUBmYWtlLmRvbWFpbjAeFw0wMjAxMTYwNTA5NTlaFw0xMjAxMTQw\n"
	"NTA5NTlaMIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjE8MDoG\n"
	"A1UEChMzUmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBBdXRob3Jp\n"
	"dHkgKFJJQUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQDExBKYWNr\n"
	"b3YgYWwtVHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9tYWluMIGf\n"
	"MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7QdDfFIrJn3X24hKmpkyk3TG0Ivxd\n"
	"K2wWmDPXq1wjr8lUTwrA6hM5Ba9N36jLieWpXhviLOWu9DBza5GmtgCuXloATKTC\n"
	"94xOdKHlciTVujG3wDlLDB5e710Kar84nnj6VueL1RyZ0bmP5PANa4mbGW9Tqc7J\n"
	"CkBTTW2y9d0SgQIDAQABo4IBFTCCAREwHQYDVR0OBBYEFEn7RXISxMzhRaHTCJ6V\n"
	"xCxtVT8XMIHhBgNVHSMEgdkwgdaAFEn7RXISxMzhRaHTCJ6VxCxtVT8XoYG6pIG3\n"
	"MIG0MQswCQYDVQQGEwJOWjETMBEGA1UEBxMKV2VsbGluZ3RvbjE8MDoGA1UEChMz\n"
	"UmVhbGx5IElycmVzcG9uc2libGUgQXV0aG9yaXNhdGlvbiBBdXRob3JpdHkgKFJJ\n"
	"QUEpMRYwFAYDVQQLEw1DZXJ0LXN0YW1waW5nMRkwFwYDVQQDExBKYWNrb3YgYWwt\n"
	"VHJhZGVzMR8wHQYJKoZIhvcNAQkBFhBub25lQGZha2UuZG9tYWluggEAMAwGA1Ud\n"
	"EwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAYQo95V/NY+eKxYxkhibZiUQygph+\n"
	"gTfgbDG20MsnH6+8//w5ArHauFCgDrf0P2VyACgq+N4pBTWFGaAaLwbjKy9HCe2E\n"
	"j9C91tO1CqDS4MJkDB5AP13FTkK6fP1ZCiTQranOAp3DlGWTTWsFVyW5kVfQ9diS\n"
	"ZOyJZ9Fit5XM2X0=\n"
	"-----END CERTIFICATE-----\n";


================================================
FILE: include/mhvtl_log.h
================================================
/*
 * This handles any SCSI OP 'log sense / log select'
 *
 * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail dot com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * See comments in vtltape.c for a more complete version release...
 *
 */

#ifndef MHVTL_LOG_H
#define MHVTL_LOG_H

#include <stdint.h>
#include "mhvtl_list.h"

struct lu_phy_attr;
typedef void (*init_pg_fn)(void *log_ptr);

/*
 * Process the LOG_SENSE page definitions
 */
#define SUPPORTED_LOG_PAGES			0x00
#define BUFFER_UNDER_OVER_RUN		0x01
#define WRITE_ERROR_COUNTER			0x02
#define READ_ERROR_COUNTER			0x03
#define READ_REVERSE_ERROR_COUNTER	0x04
#define VERIFY_ERROR_COUNTER		0x05
#define NON_MEDIUM_ERROR_COUNTER	0x06
#define LAST_n_ERROR				0x07
#define FORMAT_STATUS				0x08
#define LAST_n_DEFERRED_ERROR		0x0b
#define SEQUENTIAL_ACCESS_DEVICE	0x0c
#define TEMPERATURE_PAGE			0x0d
#define START_STOP_CYCLE_COUNTER	0x0e
#define APPLICATION_CLIENT			0x0f
#define SELFTEST_RESULTS			0x10
#define DEVICE_STATUS				0x11
#define VOLUME_STATISTICS			0x17
#define TAPE_ALERT					0x2e
#define INFORMATIONAL_EXCEPTIONS	0x2f
#define TAPE_USAGE					0x30
#define TAPE_CAPACITY				0x31
#define DATA_COMPRESSION			0x32
#define PERFORMANCE_CHARACTERISTICS 0x37

#define NO_SUBPAGE 0x00

struct log_pg_list {
	struct list_head siblings;
	char			*description;
	int				 log_page_num;
	int				 log_subpage_num;
	int				 size;
	void			*p;
};

/* Log Page header */
struct log_pg_header {
	uint8_t	 pcode;
	uint8_t	 res;
	uint16_t len;
} __attribute__((packed));

/* Page Code header struct. */
struct pc_header {
	uint8_t head0;
	uint8_t head1;
	uint8_t flags;
	uint8_t len;
} __attribute__((packed));

/* Vendor Specific : 0x32 (Taken from IBM Ultrium doco) */
struct DataCompression_pg {
	struct log_pg_header pcode_head;

	struct pc_header h_ReadCompressionRatio;
	uint16_t		 ReadCompressionRatio;
	struct pc_header h_WriteCompressionRatio;
	uint16_t		 WriteCompressionRatio;
	struct pc_header h_MBytesToServer;
	uint32_t		 MBytesToServer;
	struct pc_header h_BytesToServer;
	uint32_t		 BytesToServer;
	struct pc_header h_MBytesReadFromTape;
	uint32_t		 MBytesReadFromTape;
	struct pc_header h_BytesReadFromTape;
	uint32_t		 BytesReadFromTape;

	struct pc_header h_MBytesFromServer;
	uint32_t		 MBytesFromServer;
	struct pc_header h_BytesFromServer;
	uint32_t		 BytesFromServer;
	struct pc_header h_MBytesWrittenToTape;
	uint32_t		 MBytesWrittenToTape;
	struct pc_header h_BytesWrittenToTape;
	uint32_t		 BytesWrittenToTape;
} __attribute__((packed));

/* Buffer Under/Over Run log page - 0x01 : SPC-3 (7.2.3) */
struct BufferUnderOverRun_pg {
	struct log_pg_header pcode_head;
} __attribute__((packed));

struct TapeUsage_pg {
	struct log_pg_header pcode_head;
	struct pc_header	 flagNo01;
	uint32_t			 volumeMounts;
	struct pc_header	 flagNo02;
	uint64_t			 volumeDatasetsWritten;
	struct pc_header	 flagNo03;
	uint32_t			 volWriteRetries;
	struct pc_header	 flagNo04;
	uint16_t			 volWritePerms;
	struct pc_header	 flagNo05;
	uint16_t			 volSuspendedWrites;
	struct pc_header	 flagNo06;
	uint16_t			 volFatalSuspendedWrites;
	struct pc_header	 flagNo07;
	uint64_t			 volDatasetsRead;
	struct pc_header	 flagNo08;
	uint32_t			 volReadRetries;
	struct pc_header	 flagNo09;
	uint16_t			 volReadPerms;
	struct pc_header	 flagNo10;
	uint16_t			 volSuspendedReads;
	struct pc_header	 flagNo11;
	uint16_t			 volFatalSuspendedReads;
} __attribute__((packed));

/* Self-Test Results - 0x10
 *
 */

struct selfTest_data { /* data in log parameters of selftest results */
	uint8_t	 self_test_code_results;
	uint8_t	 self_test_number;
	uint16_t accumulated_power_on_hours;
	uint64_t address_of_first_failure;
	uint8_t	 sense_key;
	uint8_t	 asc;
	uint8_t	 ascq;
	uint8_t	 vendor_specific;
} __attribute__((packed));

struct SelfTestResults_pg {

	struct log_pg_header pcode_head;

	struct pc_header	 h_result01;
	struct selfTest_data data01;

	struct pc_header	 h_result02;
	struct selfTest_data data02;

	struct pc_header	 h_result03;
	struct selfTest_data data03;

	struct pc_header	 h_result04;
	struct selfTest_data data04;

	struct pc_header	 h_result05;
	struct selfTest_data data05;

	struct pc_header	 h_result06;
	struct selfTest_data data06;

	struct pc_header	 h_result07;
	struct selfTest_data data07;

	struct pc_header	 h_result08;
	struct selfTest_data data08;

	struct pc_header	 h_result09;
	struct selfTest_data data09;

	struct pc_header	 h_result0a;
	struct selfTest_data data0a;

	struct pc_header	 h_result0b;
	struct selfTest_data data0b;

	struct pc_header	 h_result0c;
	struct selfTest_data data0c;

	struct pc_header	 h_result0d;
	struct selfTest_data data0d;

	struct pc_header	 h_result0e;
	struct selfTest_data data0e;

	struct pc_header	 h_result0f;
	struct selfTest_data data0f;

	struct pc_header	 h_result10;
	struct selfTest_data data10;

	struct pc_header	 h_result11;
	struct selfTest_data data11;

	struct pc_header	 h_result12;
	struct selfTest_data data12;

	struct pc_header	 h_result13;
	struct selfTest_data data13;

	struct pc_header	 h_result14;
	struct selfTest_data data14;

} __attribute__((packed));

struct DeviceStatus_pg {
	struct log_pg_header pcode_head;

	struct pc_header h_vhf;
	struct __attribute__((packed)) {
		struct __attribute__((packed)) {
			uint8_t DINIT : 1; /* Device Initialized - 0 not initialised*/
			uint8_t CRQRD : 1; /* Cleaning required - before media is mounted (required) */
			uint8_t CRQST : 1; /* Cleaning required - non urgent (request) */
			uint8_t WRTP : 1;  /* Physical Write Protect */
			uint8_t CMPR : 1;  /* Compression enabled */
			uint8_t MACC : 1;  /* MAM accessible */
			uint8_t HIU : 1;   /* Host Initiated Unload */
			uint8_t PAMR : 1;  /* Prevent/Allow Media Removal */
		} b4;

		struct __attribute__((packed)) {
			uint8_t MOUNTED : 1; /* Medium mounted */
			uint8_t MTHRD : 1;	 /* Medium Threaded */
			uint8_t MSTD : 1;	 /* Medium Seated */
			uint8_t RSVD_2 : 1;
			uint8_t MPRSNT : 1; /* Medium Present */
			uint8_t RAA : 1;	/* Robotic access allowed */
			uint8_t RSVD_1 : 1;
			uint8_t INXTN : 1; /* In Transition - other bits in byte 5 not stable */
		} b5;

		uint8_t b6; /* DT Device Activity */

		struct __attribute__((packed)) {
			uint8_t TAFC : 1;	/* TapeAlert state flag changed */
			uint8_t INITFC : 1; /* Interface changed */
			uint8_t RRQST : 1;	/* Recovery requested */
			uint8_t ESR : 1;	/* Encryption Service Requested */
			uint8_t EPP : 1;	/* Encryption Parameters Present */
			uint8_t TDDEC : 1;	/* Tape Diagnostic data entry created */
			uint8_t RSVD : 1;
			uint8_t VS : 1; /* Always 0 */
		} b7;

	} vhf; /* Very High Frequency data */
} __attribute__((packed));

struct TapeCapacity_pg {
	struct log_pg_header pcode_head;
	struct pc_header	 flagNo01;
	uint32_t			 partition0remaining;
	struct pc_header	 flagNo02;
	uint32_t			 partition1remaining;
	struct pc_header	 flagNo03;
	uint32_t			 partition0maximum;
	struct pc_header	 flagNo04;
	uint32_t			 partition1maximum;
} __attribute__((packed));

/* Volume Statistics - 0x17
 * SSC-4
 */
struct partition_record_header {
	uint8_t	 len;
	uint8_t	 reserved;
	uint16_t partition_no;

} __attribute__((packed));

struct partition_record_size4 {
	struct partition_record_header header;
	uint32_t					   data;
} __attribute__((packed));

struct partition_record_size6 {
	struct partition_record_header header;
	uint8_t						   data[6];
} __attribute__((packed));

struct VolumeStatistics_pg {
	struct log_pg_header pcode_head;

	struct pc_header h_PageValid;
	uint8_t			 PageValid;

	struct pc_header h_VolumeMounts;
	uint32_t		 VolumeMounts;

	struct pc_header h_VolumeDatasetsWritten;
	uint64_t		 VolumeDatasetsWritten;

	struct pc_header h_RecoveredWriteDataErrors;
	uint32_t		 RecoveredWriteDataErrors;

	struct pc_header h_UnrecoveredWriteDataErrors;
	uint16_t		 UnrecoveredWriteDataErrors;

	struct pc_header h_WriteServoErrors;
	uint16_t		 WriteServoErrors;

	struct pc_header h_UnrecoveredWriteServoErrors;
	uint16_t		 UnrecoveredWriteServoErrors;

	struct pc_header h_VolumeDatasetsRead;
	uint64_t		 VolumeDatasetsRead;

	struct pc_header h_RecoveredReadErrors;
	uint32_t		 RecoveredReadErrors;

	struct pc_header h_UnrecoveredReadErrors;
	uint16_t		 UnrecoveredReadErrors;

	struct pc_header h_LastMountUnrecoveredWriteErrors;
	uint16_t		 LastMountUnrecoveredWriteErrors;

	struct pc_header h_LastMountUnrecoveredReadErrors;
	uint16_t		 LastMountUnrecoveredReadErrors;

	struct pc_header h_LastMountMBWritten;
	uint32_t		 LastMountMBWritten;

	struct pc_header h_LastMountMBRead;
	uint32_t		 LastMountMBRead;

	struct pc_header h_LifetimeMBWritten;
	uint64_t		 LifetimeMBWritten;

	struct pc_header h_LifetimeMBRead;
	uint64_t		 LifetimeMBRead;

	struct pc_header h_LastLoadWriteCompressionRatio;
	uint16_t		 LastLoadWriteCompressionRatio;

	struct pc_header h_LastLoadReadCompressionRatio;
	uint16_t		 LastLoadReadCompressionRatio;

	struct pc_header h_MediumMountTime;
	uint8_t			 MediumMountTime[6];

	struct pc_header h_MediumReadyTime;
	uint8_t			 MediumReadyTime[6];

	struct pc_header h_TotalNativeCapacity;
	uint32_t		 TotalNativeCapacity;

	struct pc_header h_TotalUsedNativeCapacity;
	uint32_t		 TotalUsedNativeCapacity;

	struct pc_header h_AppDesignCapacity;
	uint32_t		 AppDesignCapacity;

	struct pc_header h_VolumeLifetimeRemaining;
	uint8_t			 VolumeLifetimeRemaining;

	struct pc_header h_VolumeSerialNumber;
	uint8_t			 VolumeSerialNumber[32];

	struct pc_header h_TapeLotIdentifier;
	uint8_t			 TapeLotIdentifier[8];

	struct pc_header h_VolumeBarcode;
	uint8_t			 VolumeBarcode[32];

	struct pc_header h_VolumeManufacturer;
	uint8_t			 VolumeManufacturer[8];

	struct pc_header h_VolumeLicenseCode;
	uint8_t			 VolumeLicenseCode[4];

	struct pc_header h_VolumePersonality;
	uint8_t			 VolumePersonality[9];

	struct pc_header h_WriteProtect;
	uint8_t			 WriteProtect;

	struct pc_header h_WORM;
	uint8_t			 WORM;

	struct pc_header h_TempExceeded;
	uint8_t			 TempExceeded;

	struct pc_header h_BOMPasses;
	uint32_t		 BOMPasses;

	struct pc_header h_MOTPasses;
	uint32_t		 MOTPasses;

	/* size depends on actual nb of partitions
	=> we put max size by default and adapt dynamically later */
	struct pc_header			  h_FirstEncryptedLogicalObj;
	struct partition_record_size6 FirstEncryptedLogicalObj[MAX_PARTITIONS];

	struct pc_header			  h_FirstUnencryptedLogicalObj;
	struct partition_record_size6 FirstUnencryptedLogicalObj[MAX_PARTITIONS];

	struct pc_header			  h_ApproxNativeCapacityPartition;
	struct partition_record_size4 ApproxNativeCapacityPartition[MAX_PARTITIONS];

	struct pc_header			  h_ApproxUsedNativeCapacityPartition;
	struct partition_record_size4 ApproxUsedNativeCapacityPartition[MAX_PARTITIONS];

	struct pc_header			  h_RemainingCapacityToEWPartition;
	struct partition_record_size4 RemainingCapacityToEWPartition[MAX_PARTITIONS];

} __attribute__((packed));

struct TapeAlert_flag {
	struct pc_header flag;
	uint8_t			 value;
} __attribute__((packed));

/* Tape Alert Log Page - 0x2E
 * SSC-3 (8.2.3)
 */
struct TapeAlert_pg {
	struct log_pg_header pcode_head;

	struct TapeAlert_flag TapeAlert[64];
} __attribute__((packed));

/* Temperature Log Page - 0x0d
 * SPC-3 (7.2.13)
 */
struct Temperature_pg {
	struct log_pg_header pcode_head;
	struct pc_header	 header;
	uint16_t			 temperature;
} __attribute__((packed));

/* Write/Read/Read Reverse
 * Error Counter log page - 0x02, 0x03, 0x04
 * SPC-3 (7.2.4)
 */
struct ErrorCounter_pg {
	struct log_pg_header pcode_head;

	struct pc_header h_err_correctedWODelay;
	uint32_t		 err_correctedWODelay;
	struct pc_header h_err_correctedWDelay;
	uint32_t		 err_correctedWDelay;
	struct pc_header h_totalReTry;
	uint32_t		 totalReTry;
	struct pc_header h_totalErrorsCorrected;
	uint32_t		 totalErrorsCorrected;
	struct pc_header h_correctAlgorithm;
	uint32_t		 correctAlgorithm;
	struct pc_header h_bytesProcessed;
	uint64_t		 bytesProcessed;
	struct pc_header h_uncorrectedErrors;
	uint32_t		 uncorrectedErrors;
	struct pc_header h_readErrorsSinceLast;
	uint32_t		 readErrorsSinceLast;
	struct pc_header h_totalRawReadError;
	uint32_t		 totalRawReadError;
	struct pc_header h_totalDropoutError;
	uint32_t		 totalDropoutError;
	struct pc_header h_totalServoTracking;
	uint32_t		 totalServoTracking;
} __attribute__((packed));

/* Sequential-Access
 * Device log page - 0x0C
 * SSC-3 (Ch 8.2.2)
 */
struct SequentialAccessDevice_pg {
	struct log_pg_header pcode_head;

	struct pc_header h_writeDataB4;
	uint64_t		 writeDataB4Compression; /* Write. Bytes from initiator */
	struct pc_header h_writeData_Af;
	uint64_t		 writeDataAfCompression; /* Write. Bytes written to media */

	struct pc_header h_readData_b4;
	uint64_t		 readDataB4Compression; /* Read. Bytes read from media */
	struct pc_header h_readData_Af;
	uint64_t		 readDataAfCompression; /* Read. Bytes to initiator */

	struct pc_header h_bop_eod;
	uint32_t		 capacity_bop_eod; /* Native capacity BOT to EOD */

	struct pc_header h_bop_ew;
	uint32_t		 capacity_bop_ew; /* Native capacity BOP to EW */

	struct pc_header h_ew_leop;
	uint32_t		 capacity_ew_leop; /* Native capacity EW and
										* Logical End Of Partition */

	struct pc_header h_bop_curr;
	uint32_t		 capacity_bop_curr; /* Native capacity BOP to curr pos */

	struct pc_header h_buffer;
	uint32_t		 capacity_buffer; /* Native capacity in buffer */

	struct pc_header h_cleaning;
	uint64_t		 TapeAlert;

	struct pc_header h_mbytes_processed;
	uint32_t		 mbytes_processed; /* MB since cleaning */

	struct pc_header h_load_cycle;
	uint32_t		 load_cycle; /* Total number of load cycles over drive lifetime*/

	struct pc_header h_clean;
	uint32_t		 clean_cycle; /* Total number of cleans over drive lifetime */

} __attribute__((packed));

/* Performance Characteristics Log Page - 0x37
 * Sample
 */
struct PerformanceCharacteristics_pg {
	struct log_pg_header pcode_head;

	struct pc_header h_DriveEfficiency;
	uint8_t			 DriveEfficiency;

} __attribute__((packed));

void set_current_state(int s);
int	 get_tape_load_status();
void set_tape_load_status(int s);

void set_lp_11_macc(int flag);
void set_lp11_medium_present(int flag); /* Update LogPage 11 'Medium Present' bit */
void set_lp11_compression(int flag);	/* Update LogPage 11 compression bit */
void set_lp_11_wp(int flag);
void setTapeAlert(struct TapeAlert_pg *, uint64_t); /* in vtllib.c, never used */
void initTapeAlert(struct TapeAlert_pg *);
void dealloc_all_log_pages(struct lu_phy_attr *lu);

void update_VolumeStatistics(struct VolumeStatistics_pg *pg, struct priv_lu_ssc *lu_priv);
int	 update_TapeAlert(uint64_t flags);
int	 set_TapeAlert(uint64_t flags);
void update_TapeUsage(struct TapeUsage_pg *b);
void update_TapeCapacity(struct TapeCapacity_pg *pg);
void update_SequentialAccessDevice(struct SequentialAccessDevice_pg *sa);

struct log_pg_list *lookup_log_pg(struct list_head *l, uint8_t page, uint8_t subpage);
int					alloc_log_page(struct lu_phy_attr *lu,
								   uint8_t page, uint8_t subpage,
								   init_pg_fn init_log_pg,
								   size_t	  pg_size);

int add_log_write_err_counter(struct lu_phy_attr *lu);
int add_log_read_err_counter(struct lu_phy_attr *lu);
int add_log_sequential_access(struct lu_phy_attr *lu);
int add_log_temperature_page(struct lu_phy_attr *lu);
int add_log_selftest_results(struct lu_phy_attr *lu);
int add_log_volume_statistics(struct lu_phy_attr *lu);
int add_log_tape_alert(struct lu_phy_attr *lu);
int add_log_tape_usage(struct lu_phy_attr *lu);
int add_log_tape_capacity(struct lu_phy_attr *lu);
int add_log_data_compression(struct lu_phy_attr *lu);
int add_log_device_status(struct lu_phy_attr *lu);
int add_log_performance_char
Download .txt
gitextract_1xsiiwpt/

├── .clang-format
├── .github/
│   └── workflows/
│       └── codeql.yml
├── .gitignore
├── COPYING
├── ChangeLog
├── INSTALL
├── Makefile
├── README
├── ccan/
│   └── ccan/
│       └── crc32c/
│           ├── _info
│           ├── benchmark/
│           │   ├── Makefile
│           │   └── bench.c
│           ├── crc32c.c
│           ├── crc32c.h
│           └── test/
│               ├── api-crc32c.c
│               └── run-crc32c.c
├── config.mk
├── doc/
│   ├── 4_library_example/
│   │   ├── device.conf
│   │   ├── library_contents.10
│   │   ├── library_contents.20
│   │   ├── library_contents.30
│   │   ├── library_contents.40
│   │   └── mhvtl.conf
│   └── index.html
├── etc/
│   ├── .gitignore
│   ├── Makefile
│   ├── generate_device_conf.in
│   ├── generate_library_contents.in
│   ├── library_contents.sample
│   ├── mhvtl-load-modules.service.in
│   ├── mhvtl.conf.in
│   ├── mhvtl.target
│   ├── vtllibrary@.service.in
│   └── vtltape@.service.in
├── include/
│   ├── common/
│   │   ├── logging.h
│   │   ├── mhvtl_scsi.h
│   │   ├── vtl_common.h
│   │   ├── vtl_u.h
│   │   └── vtltape_pem.h
│   ├── mhvtl_log.h
│   ├── mode.h
│   ├── smc.h
│   ├── spc.h
│   ├── ssc.h
│   ├── utils/
│   │   ├── be_byteshift.h
│   │   ├── lzoconf.h
│   │   ├── lzodefs.h
│   │   ├── mhvtl_list.h
│   │   ├── mhvtl_update.h
│   │   ├── minilzo.h
│   │   ├── q.h
│   │   ├── security_protocol.h
│   │   └── subprocess.h
│   ├── vtlcart.h
│   └── vtllib.h
├── kernel/
│   ├── .gitignore
│   ├── Makefile
│   ├── backport.h
│   ├── config.sh
│   ├── fetch.c
│   ├── fetch24.c
│   ├── fetch26.c
│   ├── fetch27.c
│   ├── fetch50.c
│   └── mhvtl.c
├── man/
│   ├── Makefile
│   ├── device.conf.5.in
│   ├── dump_tape.1.in
│   ├── edit_tape.1.in
│   ├── generate_device_conf.1.in
│   ├── generate_library_contents.1.in
│   ├── library_contents.5.in
│   ├── make_vtl_media.1.in
│   ├── mhvtl.conf.5.in
│   ├── mhvtl_kernel_mod_build.1.in
│   ├── mktape.1.in
│   ├── preload_tape.1.in
│   ├── tapeexerciser.1.in
│   ├── update_device.conf.1.in
│   ├── vtlcmd.1.in
│   ├── vtllibrary.1.in
│   └── vtltape.1.in
├── mhvtl-utils.spec
├── scripts/
│   ├── 70-persistent-generic.rules
│   ├── 70-persistent-tape.rules
│   ├── Makefile
│   ├── NetBackup/
│   │   ├── drive_stats.pl
│   │   └── vlt_endeject_notify.pl
│   ├── build-persistent-tape-rules.sh
│   ├── centos_configure.sh
│   ├── checkarch.sh
│   ├── checkpatch.pl
│   ├── lio_target_passthru.sh
│   ├── mhvtl-1.4.ebuild
│   ├── rescan-scsi-bus.sh
│   ├── start-mhvtl-scst.sh
│   ├── stgt-target-setup.conf
│   ├── test_lbp.sh
│   └── update_device.conf.in
├── tcopy/
│   ├── Makefile
│   ├── pathnames.h
│   ├── tcopy.1
│   └── tcopy.c
├── todo
├── usr/
│   ├── .gitignore
│   ├── Makefile
│   ├── cmd/
│   │   ├── dump_messageQ.c
│   │   ├── edit_tape.c
│   │   ├── make_scsi_dev
│   │   ├── make_vtl_media.in
│   │   ├── mhvtl-device-conf-generator.c
│   │   ├── mhvtl_kernel_mod_build.in
│   │   ├── mktape.c
│   │   ├── tape_util.c
│   │   ├── tapeexerciser.c
│   │   ├── vtlcmd.c
│   │   ├── vtllibrary.c
│   │   └── vtltape.c
│   ├── mhvtl_io.c
│   ├── mhvtl_log.c
│   ├── mode.c
│   ├── pm/
│   │   ├── ait_pm.c
│   │   ├── default_smc_pm.c
│   │   ├── default_ssc_pm.c
│   │   ├── hp_smc_pm.c
│   │   ├── hp_ultrium_pm.c
│   │   ├── ibm_03592_pm.c
│   │   ├── ibm_smc_pm.c
│   │   ├── overland_pm.c
│   │   ├── quantum_dlt_pm.c
│   │   ├── scalar_pm.c
│   │   ├── spectra_pm.c
│   │   ├── stk9x40_pm.c
│   │   ├── stklxx_pm.c
│   │   ├── t10000_pm.c
│   │   └── ult3580_pm.c
│   ├── smc.c
│   ├── spc.c
│   ├── ssc.c
│   ├── utils/
│   │   ├── README.LZO
│   │   ├── crc32c.c
│   │   ├── mhvtl_update.c
│   │   ├── minilzo.c
│   │   ├── q.c
│   │   ├── reed-solomon.c
│   │   ├── subprocess.c
│   │   └── validate_crc.c
│   ├── vtl_cart_type.c
│   ├── vtlcart.c
│   ├── vtlcart_v1.c
│   ├── vtlcart_v1_mtr.c
│   └── vtllib.c
├── vagrant/
│   ├── README.MD
│   ├── Vagrantfile
│   └── install.sh
└── webgui/
    └── index.php
Download .txt
SYMBOL INDEX (1450 symbols across 69 files)

FILE: ccan/ccan/crc32c/benchmark/bench.c
  function main (line 10) | int main(int argc, char *argv[])

FILE: ccan/ccan/crc32c/crc32c.c
  function gf2_matrix_times (line 61) | static inline uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec) {
  function gf2_matrix_square (line 74) | static inline void gf2_matrix_square(uint32_t *square, uint32_t *mat) {
  function crc32c_zeros_op (line 84) | static void crc32c_zeros_op(uint32_t *even, size_t len) {
  function crc32c_zeros (line 120) | static void crc32c_zeros(uint32_t zeros[][256], size_t len) {
  function crc32c_shift (line 133) | static inline uint32_t crc32c_shift(uint32_t zeros[][256], uint32_t crc) {
  function crc32c_init_hw (line 154) | static void crc32c_init_hw(void) {
  function crc32c_hw (line 161) | static uint32_t crc32c_hw(uint32_t crc, void const *buf, size_t len) {
  function crc32c (line 251) | uint32_t crc32c(uint32_t crc, void const *buf, size_t len) {
  function crc32c (line 258) | uint32_t crc32c(uint32_t crc, void const *buf, size_t len) {
  function crc32c_init_sw_little (line 267) | static void crc32c_init_sw_little(void) {
  function crc32c_sw_little (line 292) | static uint32_t crc32c_sw_little(uint32_t crc, void const *buf, size_t l...
  function swap (line 331) | static inline uint64_t swap(uint64_t x) {
  function crc32c_init_sw_big (line 342) | static void crc32c_init_sw_big(void) {
  function crc32c_sw_big (line 368) | static uint32_t crc32c_sw_big(uint32_t crc, void const *buf, size_t len) {
  function crc32c_sw (line 409) | static uint32_t crc32c_sw(uint32_t crc, void const *buf, size_t len) {

FILE: ccan/ccan/crc32c/test/api-crc32c.c
  function main (line 18) | int main(void)

FILE: ccan/ccan/crc32c/test/run-crc32c.c
  function main (line 20) | int main(void)

FILE: include/common/vtl_common.h
  type mhvtl_header (line 23) | struct mhvtl_header {
  type mhvtl_ds (line 29) | struct mhvtl_ds {
  type mhvtl_ctl (line 37) | struct mhvtl_ctl {

FILE: include/common/vtl_u.h
  type mhvtl_event (line 6) | struct mhvtl_event {

FILE: include/mhvtl_log.h
  type lu_phy_attr (line 30) | struct lu_phy_attr
  type log_pg_list (line 62) | struct log_pg_list {
  type log_pg_header (line 72) | struct log_pg_header {
  type pc_header (line 79) | struct pc_header {
  type DataCompression_pg (line 87) | struct DataCompression_pg {
  type BufferUnderOverRun_pg (line 114) | struct BufferUnderOverRun_pg {
  type TapeUsage_pg (line 118) | struct TapeUsage_pg {
  type selfTest_data (line 148) | struct selfTest_data { /* data in log parameters of selftest results */
  type SelfTestResults_pg (line 159) | struct SelfTestResults_pg {
  type DeviceStatus_pg (line 225) | struct DeviceStatus_pg {
  type TapeCapacity_pg (line 268) | struct TapeCapacity_pg {
  type partition_record_header (line 283) | struct partition_record_header {
  type partition_record_size4 (line 290) | struct partition_record_size4 {
  type partition_record_size6 (line 295) | struct partition_record_size6 {
  type VolumeStatistics_pg (line 300) | struct VolumeStatistics_pg {
  type TapeAlert_flag (line 427) | struct TapeAlert_flag {
  type TapeAlert_pg (line 435) | struct TapeAlert_pg {
  type Temperature_pg (line 444) | struct Temperature_pg {
  type ErrorCounter_pg (line 454) | struct ErrorCounter_pg {
  type SequentialAccessDevice_pg (line 485) | struct SequentialAccessDevice_pg {
  type PerformanceCharacteristics_pg (line 531) | struct PerformanceCharacteristics_pg {
  type TapeAlert_pg (line 547) | struct TapeAlert_pg
  type TapeAlert_pg (line 548) | struct TapeAlert_pg
  type lu_phy_attr (line 549) | struct lu_phy_attr
  type VolumeStatistics_pg (line 551) | struct VolumeStatistics_pg
  type priv_lu_ssc (line 551) | struct priv_lu_ssc
  type TapeUsage_pg (line 554) | struct TapeUsage_pg
  type TapeCapacity_pg (line 555) | struct TapeCapacity_pg
  type SequentialAccessDevice_pg (line 556) | struct SequentialAccessDevice_pg
  type log_pg_list (line 558) | struct log_pg_list
  type list_head (line 558) | struct list_head
  type lu_phy_attr (line 559) | struct lu_phy_attr
  type lu_phy_attr (line 564) | struct lu_phy_attr
  type lu_phy_attr (line 565) | struct lu_phy_attr
  type lu_phy_attr (line 566) | struct lu_phy_attr
  type lu_phy_attr (line 567) | struct lu_phy_attr
  type lu_phy_attr (line 568) | struct lu_phy_attr
  type lu_phy_attr (line 569) | struct lu_phy_attr
  type lu_phy_attr (line 570) | struct lu_phy_attr
  type lu_phy_attr (line 571) | struct lu_phy_attr
  type lu_phy_attr (line 572) | struct lu_phy_attr
  type lu_phy_attr (line 573) | struct lu_phy_attr
  type lu_phy_attr (line 574) | struct lu_phy_attr
  type lu_phy_attr (line 575) | struct lu_phy_attr

FILE: include/mode.h
  type lu_phy_attr (line 29) | struct lu_phy_attr
  type lu_phy_attr (line 31) | struct lu_phy_attr
  type lu_phy_attr (line 32) | struct lu_phy_attr
  type lu_phy_attr (line 33) | struct lu_phy_attr
  type lu_phy_attr (line 34) | struct lu_phy_attr
  type lu_phy_attr (line 35) | struct lu_phy_attr
  type lu_phy_attr (line 36) | struct lu_phy_attr
  type lu_phy_attr (line 37) | struct lu_phy_attr
  type lu_phy_attr (line 38) | struct lu_phy_attr
  type lu_phy_attr (line 39) | struct lu_phy_attr
  type lu_phy_attr (line 40) | struct lu_phy_attr
  type lu_phy_attr (line 41) | struct lu_phy_attr
  type lu_phy_attr (line 42) | struct lu_phy_attr
  type lu_phy_attr (line 43) | struct lu_phy_attr
  type lu_phy_attr (line 44) | struct lu_phy_attr
  type lu_phy_attr (line 45) | struct lu_phy_attr
  type lu_phy_attr (line 46) | struct lu_phy_attr
  type lu_phy_attr (line 47) | struct lu_phy_attr
  type lu_phy_attr (line 49) | struct lu_phy_attr
  type lu_phy_attr (line 50) | struct lu_phy_attr
  type lu_phy_attr (line 51) | struct lu_phy_attr
  type lu_phy_attr (line 52) | struct lu_phy_attr
  type lu_phy_attr (line 53) | struct lu_phy_attr
  type scsi_cmd (line 54) | struct scsi_cmd
  type lu_phy_attr (line 55) | struct lu_phy_attr
  type lu_phy_attr (line 56) | struct lu_phy_attr
  type scsi_cmd (line 58) | struct scsi_cmd
  type scsi_cmd (line 59) | struct scsi_cmd
  type scsi_cmd (line 60) | struct scsi_cmd
  type scsi_cmd (line 61) | struct scsi_cmd

FILE: include/smc.h
  type scsi_cmd (line 6) | struct scsi_cmd
  type s_info (line 7) | struct s_info
  type smc_personality_template (line 21) | struct smc_personality_template {
  type scsi_cmd (line 38) | struct scsi_cmd
  type scsi_cmd (line 39) | struct scsi_cmd
  type scsi_cmd (line 40) | struct scsi_cmd
  type scsi_cmd (line 41) | struct scsi_cmd
  type scsi_cmd (line 42) | struct scsi_cmd
  type scsi_cmd (line 43) | struct scsi_cmd
  type scsi_cmd (line 44) | struct scsi_cmd
  type scsi_cmd (line 45) | struct scsi_cmd
  type s_info (line 50) | struct s_info
  type s_info (line 51) | struct s_info
  type s_info (line 52) | struct s_info
  type s_info (line 53) | struct s_info
  type s_info (line 53) | struct s_info
  type lu_phy_attr (line 55) | struct lu_phy_attr
  type lu_phy_attr (line 56) | struct lu_phy_attr
  type lu_phy_attr (line 57) | struct lu_phy_attr
  type lu_phy_attr (line 58) | struct lu_phy_attr
  type lu_phy_attr (line 59) | struct lu_phy_attr
  type lu_phy_attr (line 60) | struct lu_phy_attr
  type lu_phy_attr (line 61) | struct lu_phy_attr
  type lu_phy_attr (line 62) | struct lu_phy_attr
  type lu_phy_attr (line 63) | struct lu_phy_attr
  type lu_phy_attr (line 64) | struct lu_phy_attr
  type lu_phy_attr (line 65) | struct lu_phy_attr
  type lu_phy_attr (line 66) | struct lu_phy_attr
  type lu_phy_attr (line 67) | struct lu_phy_attr
  type lu_phy_attr (line 68) | struct lu_phy_attr
  type smc_personality_template (line 69) | struct smc_personality_template
  type s_info (line 70) | struct s_info

FILE: include/spc.h
  type scsi_cmd (line 7) | struct scsi_cmd
  type mhvtl_ds (line 15) | struct mhvtl_ds
  type mhvtl_ds (line 16) | struct mhvtl_ds
  type scsi_cmd (line 18) | struct scsi_cmd
  type scsi_cmd (line 19) | struct scsi_cmd
  type scsi_cmd (line 20) | struct scsi_cmd
  type scsi_cmd (line 21) | struct scsi_cmd
  type scsi_cmd (line 22) | struct scsi_cmd
  type scsi_cmd (line 23) | struct scsi_cmd
  type scsi_cmd (line 24) | struct scsi_cmd
  type scsi_cmd (line 25) | struct scsi_cmd
  type scsi_cmd (line 26) | struct scsi_cmd
  type scsi_cmd (line 27) | struct scsi_cmd
  type scsi_cmd (line 28) | struct scsi_cmd
  type scsi_cmd (line 29) | struct scsi_cmd
  type scsi_cmd (line 30) | struct scsi_cmd

FILE: include/ssc.h
  type mhvtl_ds (line 10) | struct mhvtl_ds
  type scsi_cmd (line 11) | struct scsi_cmd
  type name_to_media_info (line 38) | struct name_to_media_info {
  type ssc_personality_template (line 45) | struct ssc_personality_template {
  type delay_list (line 94) | enum delay_list {
  type media_details (line 118) | struct media_details {
  type priv_lu_ssc (line 124) | struct priv_lu_ssc {
  type verify_6_bits (line 203) | struct verify_6_bits {
  type read_position_information_short (line 214) | struct read_position_information_short {
  type read_position_information_long (line 225) | struct read_position_information_long {
  type read_position_information_extended (line 235) | struct read_position_information_extended {
  type read_position_information_short (line 248) | struct read_position_information_short {
  type read_position_information_long (line 259) | struct read_position_information_long {
  type read_position_information_extended (line 269) | struct read_position_information_extended {
  type ssc_personality_template (line 282) | struct ssc_personality_template
  type scsi_cmd (line 285) | struct scsi_cmd
  type scsi_cmd (line 287) | struct scsi_cmd
  type scsi_cmd (line 288) | struct scsi_cmd
  type scsi_cmd (line 289) | struct scsi_cmd
  type scsi_cmd (line 290) | struct scsi_cmd
  type scsi_cmd (line 291) | struct scsi_cmd
  type scsi_cmd (line 292) | struct scsi_cmd
  type scsi_cmd (line 293) | struct scsi_cmd
  type scsi_cmd (line 294) | struct scsi_cmd
  type scsi_cmd (line 295) | struct scsi_cmd
  type scsi_cmd (line 296) | struct scsi_cmd
  type scsi_cmd (line 297) | struct scsi_cmd
  type scsi_cmd (line 298) | struct scsi_cmd
  type scsi_cmd (line 299) | struct scsi_cmd
  type scsi_cmd (line 300) | struct scsi_cmd
  type scsi_cmd (line 301) | struct scsi_cmd
  type scsi_cmd (line 302) | struct scsi_cmd
  type scsi_cmd (line 303) | struct scsi_cmd
  type scsi_cmd (line 304) | struct scsi_cmd
  type scsi_cmd (line 305) | struct scsi_cmd
  type scsi_cmd (line 306) | struct scsi_cmd
  type scsi_cmd (line 307) | struct scsi_cmd
  type scsi_cmd (line 308) | struct scsi_cmd
  type scsi_cmd (line 309) | struct scsi_cmd
  type scsi_cmd (line 310) | struct scsi_cmd
  type scsi_cmd (line 311) | struct scsi_cmd
  type scsi_cmd (line 312) | struct scsi_cmd
  type scsi_cmd (line 313) | struct scsi_cmd
  type scsi_cmd (line 314) | struct scsi_cmd
  type scsi_cmd (line 315) | struct scsi_cmd
  type scsi_cmd (line 316) | struct scsi_cmd
  type scsi_cmd (line 317) | struct scsi_cmd
  type scsi_cmd (line 318) | struct scsi_cmd
  type scsi_cmd (line 319) | struct scsi_cmd
  type scsi_cmd (line 320) | struct scsi_cmd
  type scsi_cmd (line 321) | struct scsi_cmd
  type scsi_cmd (line 322) | struct scsi_cmd
  type lu_phy_attr (line 325) | struct lu_phy_attr
  type lu_phy_attr (line 326) | struct lu_phy_attr
  type lu_phy_attr (line 327) | struct lu_phy_attr
  type lu_phy_attr (line 328) | struct lu_phy_attr
  type lu_phy_attr (line 329) | struct lu_phy_attr
  type lu_phy_attr (line 330) | struct lu_phy_attr
  type lu_phy_attr (line 331) | struct lu_phy_attr
  type lu_phy_attr (line 332) | struct lu_phy_attr
  type lu_phy_attr (line 333) | struct lu_phy_attr
  type lu_phy_attr (line 334) | struct lu_phy_attr
  type lu_phy_attr (line 335) | struct lu_phy_attr
  type lu_phy_attr (line 336) | struct lu_phy_attr
  type lu_phy_attr (line 337) | struct lu_phy_attr
  type lu_phy_attr (line 338) | struct lu_phy_attr
  type lu_phy_attr (line 339) | struct lu_phy_attr
  type lu_phy_attr (line 340) | struct lu_phy_attr
  type lu_phy_attr (line 341) | struct lu_phy_attr
  type lu_phy_attr (line 342) | struct lu_phy_attr
  type lu_phy_attr (line 343) | struct lu_phy_attr
  type lu_phy_attr (line 344) | struct lu_phy_attr
  type lu_phy_attr (line 345) | struct lu_phy_attr
  type lu_phy_attr (line 346) | struct lu_phy_attr
  type lu_phy_attr (line 347) | struct lu_phy_attr
  type lu_phy_attr (line 348) | struct lu_phy_attr
  type lu_phy_attr (line 349) | struct lu_phy_attr
  type lu_phy_attr (line 350) | struct lu_phy_attr
  type lu_phy_attr (line 351) | struct lu_phy_attr
  type lu_phy_attr (line 352) | struct lu_phy_attr
  type lu_phy_attr (line 353) | struct lu_phy_attr
  type lu_phy_attr (line 354) | struct lu_phy_attr
  type lu_phy_attr (line 355) | struct lu_phy_attr
  type lu_phy_attr (line 356) | struct lu_phy_attr
  type lu_phy_attr (line 357) | struct lu_phy_attr
  type lu_phy_attr (line 358) | struct lu_phy_attr
  type lu_phy_attr (line 359) | struct lu_phy_attr
  type lu_phy_attr (line 360) | struct lu_phy_attr
  type lu_phy_attr (line 361) | struct lu_phy_attr
  type lu_phy_attr (line 362) | struct lu_phy_attr
  type lu_phy_attr (line 363) | struct lu_phy_attr
  type lu_phy_attr (line 365) | struct lu_phy_attr
  type scsi_cmd (line 367) | struct scsi_cmd
  type scsi_cmd (line 368) | struct scsi_cmd
  type list_head (line 369) | struct list_head
  type scsi_cmd (line 370) | struct scsi_cmd
  type scsi_cmd (line 371) | struct scsi_cmd
  type scsi_cmd (line 372) | struct scsi_cmd
  type scsi_cmd (line 373) | struct scsi_cmd
  type priv_lu_ssc (line 374) | struct priv_lu_ssc
  type mhvtl_ds (line 375) | struct mhvtl_ds
  type scsi_cmd (line 382) | struct scsi_cmd

FILE: include/utils/be_byteshift.h
  function __get_unaligned_be16 (line 6) | static inline uint16_t __get_unaligned_be16(const uint8_t *p) {
  function __get_unaligned_be32 (line 10) | static inline uint32_t __get_unaligned_be32(const uint8_t *p) {
  function __get_unaligned_be64 (line 14) | static inline uint64_t __get_unaligned_be64(const uint8_t *p) {
  function __put_unaligned_be16 (line 19) | static inline void __put_unaligned_be16(uint16_t val, uint8_t *p) {
  function __put_unaligned_be32 (line 24) | static inline void __put_unaligned_be32(uint32_t val, uint8_t *p) {
  function __put_unaligned_be64 (line 29) | static inline void __put_unaligned_be64(uint64_t val, uint8_t *p) {
  function get_unaligned_be16 (line 34) | static inline uint16_t get_unaligned_be16(const void *p) {
  function get_unaligned_be24 (line 38) | static inline uint32_t get_unaligned_be24(const uint8_t *p) {
  function get_unaligned_be32 (line 42) | static inline uint32_t get_unaligned_be32(const void *p) {
  function get_unaligned_be48 (line 46) | static inline uint64_t get_unaligned_be48(const void *p) {
  function get_unaligned_be64 (line 51) | static inline uint64_t get_unaligned_be64(const void *p) {
  function put_unaligned_be16 (line 55) | static inline void put_unaligned_be16(uint16_t val, void *p) {
  function put_unaligned_be24 (line 59) | static inline void put_unaligned_be24(uint32_t val, void *p) {
  function put_unaligned_be32 (line 65) | static inline void put_unaligned_be32(uint32_t val, void *p) {
  function put_unaligned_be48 (line 69) | static inline void put_unaligned_be48(uint64_t val, void *p) {
  function put_unaligned_be64 (line 74) | static inline void put_unaligned_be64(uint64_t val, void *p) {

FILE: include/utils/lzoconf.h
  type lzo_uint (line 90) | typedef unsigned __int64 lzo_uint;
  type __int64 (line 91) | typedef __int64			 lzo_int;
  type lzo_ullong_t (line 94) | typedef lzo_ullong_t lzo_uint;
  type lzo_llong_t (line 95) | typedef lzo_llong_t	 lzo_int;
  type lzo_uint (line 103) | typedef unsigned int lzo_uint;
  type lzo_int (line 104) | typedef int			 lzo_int;
  type lzo_uint (line 111) | typedef unsigned long lzo_uint;
  type lzo_int (line 112) | typedef long		  lzo_int;
  type lzo_bool (line 130) | typedef int lzo_bool;
  type lzo_callback_t (line 258) | struct lzo_callback_t
  type lzo_callback_t (line 259) | typedef struct lzo_callback_t lzo_callback_t;
  type lzo_callback_t (line 269) | struct lzo_callback_t {
  type lzo_align_t (line 358) | typedef union {
  type __lzo_pu_u (line 402) | typedef union {
  type __lzo_pu32_u (line 406) | typedef union {

FILE: include/utils/lzodefs.h
  type lzo_int16e_hi_t__ (line 2744) | typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__)));
  type lzo_uint16e_hi_t__ (line 2745) | typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__)));
  type lzo_int32e_si_t__ (line 2779) | typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
  type lzo_uint32e_si_t__ (line 2780) | typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
  type lzo_int32e_si_t__ (line 2785) | typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
  type lzo_uint32e_si_t__ (line 2786) | typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
  type __w64 (line 2928) | typedef __w64 int                lzo_intptr_t;
  type lzo_uintptr_t (line 2929) | typedef __w64 unsigned int       lzo_uintptr_t;
  type lzo_word_t (line 2996) | typedef unsigned lzo_word_t  __attribute__((__mode__(__V16QI__)));
  type lzo_sword_t (line 2997) | typedef int      lzo_sword_t __attribute__((__mode__(__V16QI__)));

FILE: include/utils/mhvtl_list.h
  type list_head (line 18) | struct list_head {
  function INIT_LIST_HEAD (line 27) | static inline void INIT_LIST_HEAD(struct list_head *list) {
  function list_empty (line 35) | static inline int list_empty(const struct list_head *head) {
  function __list_add (line 56) | static inline void __list_add(struct list_head *newhead,
  function list_add (line 65) | static inline void list_add(struct list_head *newhead, struct list_head ...
  function list_add_tail (line 69) | static inline void list_add_tail(struct list_head *newhead, struct list_...
  function __list_del (line 73) | static inline void __list_del(struct list_head *prev, struct list_head *...
  function list_del (line 78) | static inline void list_del(struct list_head *entry) {
  function list_del_init (line 83) | static inline void list_del_init(struct list_head *entry) {
  function __list_splice (line 88) | static inline void __list_splice(const struct list_head *list,
  function list_splice_init (line 101) | static inline void list_splice_init(struct list_head *list,

FILE: include/utils/q.h
  type q_msg (line 28) | struct q_msg {
  type q_entry (line 39) | struct q_entry {

FILE: include/utils/security_protocol.h
  type sa (line 26) | struct sa {

FILE: include/vtlcart.h
  type MAM (line 28) | struct MAM
  type encryption (line 44) | struct encryption {
  type blk_header (line 70) | struct blk_header {
  type encryption (line 217) | struct encryption
  type MAM (line 223) | struct MAM

FILE: include/vtllib.h
  type conf_file (line 93) | typedef enum {
  type smc_type_slot (line 133) | struct smc_type_slot {
  type mode (line 139) | struct mode {
  type MAM_attribute_idx (line 154) | enum MAM_attribute_idx {
  type MHVTL_attribute_idx (line 210) | enum MHVTL_attribute_idx {
  type MAM_attr (line 226) | struct MAM_attr {
  type MHVTL_attr (line 234) | struct MHVTL_attr {
  type MAM (line 240) | struct MAM {
  type lu_phy_attr (line 317) | struct lu_phy_attr
  type vpd (line 320) | struct vpd {
  type drive_type_list (line 325) | enum drive_type_list {
  type Media_Type_list (line 368) | enum Media_Type_list {
  type scsi_cmd (line 465) | struct scsi_cmd {
  type device_type_operations (line 484) | struct device_type_operations {
  type device_type_template (line 490) | struct device_type_template {
  type lu_phy_attr (line 497) | struct lu_phy_attr {
  type d_info (line 528) | struct d_info {
  type m_info (line 543) | struct m_info { /* Media Info */
  type s_info (line 553) | struct s_info { /* Slot Info */
  type smc_priv (line 570) | struct smc_priv {
  type density_info (line 587) | struct density_info {
  type supported_density_list (line 598) | struct supported_density_list {
  type s_sd (line 609) | struct s_sd {
  type MHVTL_STATE (line 617) | enum MHVTL_STATE {
  type MAM (line 656) | struct MAM
  type s_sd (line 665) | struct s_sd
  type mode (line 676) | struct mode
  type mode (line 677) | struct mode
  type list_head (line 677) | struct list_head
  type mhvtl_ds (line 678) | struct mhvtl_ds
  type scsi_cmd (line 692) | struct scsi_cmd
  type vpd (line 694) | struct vpd
  type vpd (line 695) | struct vpd
  type list_head (line 696) | struct list_head
  type mhvtl_ctl (line 698) | struct mhvtl_ctl
  type mhvtl_ds (line 700) | struct mhvtl_ds
  type mhvtl_ds (line 701) | struct mhvtl_ds
  type scsi_cmd (line 705) | struct scsi_cmd
  type lu_phy_attr (line 707) | struct lu_phy_attr
  type device_type_template (line 708) | struct device_type_template
  type lu_phy_attr (line 710) | struct lu_phy_attr
  type list_head (line 712) | struct list_head
  type list_head (line 713) | struct list_head
  type list_head (line 714) | struct list_head
  type list_head (line 715) | struct list_head
  type lu_phy_attr (line 721) | struct lu_phy_attr
  type lu_phy_attr (line 722) | struct lu_phy_attr
  type lu_phy_attr (line 723) | struct lu_phy_attr
  type lu_phy_attr (line 724) | struct lu_phy_attr
  type lu_phy_attr (line 725) | struct lu_phy_attr
  type lu_phy_attr (line 726) | struct lu_phy_attr
  type lu_phy_attr (line 727) | struct lu_phy_attr
  type lu_phy_attr (line 728) | struct lu_phy_attr
  type list_head (line 735) | struct list_head
  type density_info (line 735) | struct density_info
  type lu_phy_attr (line 736) | struct lu_phy_attr
  type MAM (line 739) | struct MAM
  type lu_phy_attr (line 742) | struct lu_phy_attr
  type lu_phy_attr (line 743) | struct lu_phy_attr
  type lu_phy_attr (line 745) | struct lu_phy_attr
  type smc_type_slot (line 745) | struct smc_type_slot
  type scsi_cmd (line 748) | struct scsi_cmd
  type MAM (line 752) | struct MAM
  type priv_lu_ssc (line 753) | struct priv_lu_ssc
  type lu_phy_attr (line 754) | struct lu_phy_attr
  type encryption (line 755) | struct encryption
  type blk_header (line 768) | struct blk_header

FILE: kernel/backport.h
  type slab_flags_t (line 12) | typedef unsigned __bitwise slab_flags_t;
  type kmem_cache (line 20) | struct kmem_cache
  type kmem_cache (line 28) | struct kmem_cache
  type inode (line 43) | struct inode
  type file (line 43) | struct file
  function sysfs_emit (line 59) | static int sysfs_emit(char *buf, const char *fmt, ...) {

FILE: kernel/fetch.c
  function mhvtl_fetch_to_dev_buffer (line 8) | static int mhvtl_fetch_to_dev_buffer(struct scsi_cmnd *scp, char __user ...
  function mhvtl_fill_from_user_buffer (line 66) | static int mhvtl_fill_from_user_buffer(struct scsi_cmnd *scp, char __use...
  function mhvtl_fill_from_dev_buffer (line 121) | static int mhvtl_fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned ch...

FILE: kernel/fetch24.c
  function mhvtl_fetch_to_dev_buffer (line 8) | static int mhvtl_fetch_to_dev_buffer(struct scsi_cmnd *scp, char __user ...
  function mhvtl_fill_from_user_buffer (line 74) | static int mhvtl_fill_from_user_buffer(struct scsi_cmnd *scp, char __use...
  function mhvtl_fill_from_dev_buffer (line 133) | static int mhvtl_fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned ch...

FILE: kernel/fetch26.c
  function mhvtl_sg_copy_user (line 18) | static size_t mhvtl_sg_copy_user(struct scatterlist *sgl, unsigned int n...
  function mhvtl_copy_from_user (line 71) | size_t mhvtl_copy_from_user(struct scatterlist *sgl, unsigned int nents,
  function mhvtl_copy_to_user (line 76) | size_t mhvtl_copy_to_user(struct scatterlist *sgl, unsigned int nents,
  function mhvtl_fetch_to_dev_buffer (line 87) | static int mhvtl_fetch_to_dev_buffer(struct scsi_cmnd *scp, char __user ...
  function mhvtl_fill_from_user_buffer (line 104) | static int mhvtl_fill_from_user_buffer(struct scsi_cmnd *scp, char __use...
  function mhvtl_fill_from_dev_buffer (line 125) | static int mhvtl_fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned ch...

FILE: kernel/fetch27.c
  function mhvtl_sg_copy_user (line 16) | static size_t mhvtl_sg_copy_user(struct scatterlist *sgl, unsigned int n...
  function mhvtl_copy_from_user (line 75) | static size_t mhvtl_copy_from_user(struct scatterlist *sgl, unsigned int...
  function mhvtl_copy_to_user (line 80) | static size_t mhvtl_copy_to_user(struct scatterlist *sgl, unsigned int n...
  function mhvtl_fetch_to_dev_buffer (line 91) | static int mhvtl_fetch_to_dev_buffer(struct scsi_cmnd *scp, char __user ...
  function mhvtl_fill_from_user_buffer (line 108) | static int mhvtl_fill_from_user_buffer(struct scsi_cmnd *scp, char __use...
  function mhvtl_fill_from_dev_buffer (line 129) | static int mhvtl_fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned ch...

FILE: kernel/fetch50.c
  function mhvtl_sg_copy_user (line 17) | static size_t mhvtl_sg_copy_user(struct scatterlist *sgl, unsigned int n...
  function mhvtl_copy_from_user (line 78) | static size_t mhvtl_copy_from_user(struct scatterlist *sgl, unsigned int...
  function mhvtl_copy_to_user (line 83) | static size_t mhvtl_copy_to_user(struct scatterlist *sgl, unsigned int n...
  function mhvtl_fetch_to_dev_buffer (line 94) | static int mhvtl_fetch_to_dev_buffer(struct scsi_cmnd *scp, char __user ...
  function mhvtl_fill_from_user_buffer (line 109) | static int mhvtl_fill_from_user_buffer(struct scsi_cmnd *scp, char __use...
  function mhvtl_fill_from_dev_buffer (line 127) | static int mhvtl_fill_from_dev_buffer(struct scsi_cmnd *scp, unsigned ch...

FILE: kernel/mhvtl.c
  type Scsi_Host (line 85) | struct Scsi_Host
  type scsi_cmnd (line 86) | struct scsi_cmnd
  type scsi_device (line 87) | struct scsi_device
  type scsi_target (line 88) | struct scsi_target
  type scatterlist (line 89) | struct scatterlist
  type kmem_cache (line 191) | struct kmem_cache
  type kmem_cache (line 192) | struct kmem_cache
  type mhvtl_lu_info (line 203) | struct mhvtl_lu_info {
  type mhvtl_lu_info (line 220) | struct mhvtl_lu_info
  type mhvtl_hba_info (line 222) | struct mhvtl_hba_info {
  type scsi_cmnd (line 239) | struct scsi_cmnd
  type cmd_state (line 242) | enum cmd_state {
  type mhvtl_queued_cmd (line 248) | struct mhvtl_queued_cmd {
  type device (line 265) | struct device
  type device (line 266) | struct device
  type bus_type (line 267) | struct bus_type
  type device_driver (line 269) | struct device_driver
  type scsi_cmnd (line 277) | struct scsi_cmnd
  type mhvtl_lu_info (line 277) | struct mhvtl_lu_info
  type scsi_cmnd (line 278) | struct scsi_cmnd
  type scsi_cmnd (line 280) | struct scsi_cmnd
  type timer_list (line 283) | struct timer_list
  type mhvtl_lu_info (line 287) | struct mhvtl_lu_info
  type scsi_device (line 287) | struct scsi_device
  type mhvtl_lu_info (line 288) | struct mhvtl_lu_info
  type scsi_device (line 296) | struct scsi_device
  type scsi_device (line 298) | struct scsi_device
  type queue_limits (line 298) | struct queue_limits
  type scsi_device (line 300) | struct scsi_device
  type scsi_device (line 302) | struct scsi_device
  type scsi_device (line 305) | struct scsi_device
  type scsi_device (line 307) | struct scsi_device
  type scsi_cmnd (line 312) | struct scsi_cmnd
  type scsi_cmnd (line 314) | struct scsi_cmnd
  type scsi_device (line 318) | struct scsi_device
  type scsi_device (line 320) | struct scsi_device
  type file (line 322) | struct file
  type inode (line 323) | struct inode
  type file (line 323) | struct file
  type scsi_cmnd (line 324) | struct scsi_cmnd
  type scsi_cmnd (line 325) | struct scsi_cmnd
  type scsi_cmnd (line 326) | struct scsi_cmnd
  type scsi_cmnd (line 327) | struct scsi_cmnd
  type Scsi_Host (line 328) | struct Scsi_Host
  type inode (line 329) | struct inode
  type file (line 329) | struct file
  type inode (line 330) | struct inode
  type file (line 330) | struct file
  type device (line 336) | struct device
  type scsi_host_template (line 339) | struct scsi_host_template
  type file_operations (line 384) | struct file_operations
  function mhvtl_schedule_resp (line 419) | static int mhvtl_schedule_resp(struct scsi_cmnd		*SCpnt,
  function mhvtl_resp_write_to_user (line 448) | static int mhvtl_resp_write_to_user(struct scsi_cmnd *SCpnt,
  function mhvtl_debug_queued_list (line 463) | static void mhvtl_debug_queued_list(struct mhvtl_lu_info *lu) {
  type mhvtl_hba_info (line 492) | struct mhvtl_hba_info
  type mhvtl_hba_info (line 493) | struct mhvtl_hba_info
  function mhvtl_dump_queued_list (line 505) | static void mhvtl_dump_queued_list(void) {
  function mhvtl_q_cmd (line 532) | static int mhvtl_q_cmd(struct scsi_cmnd		*scp,
  function _mhvtl_queuecommand_lck (line 584) | static int _mhvtl_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t...
  function mhvtl_queuecommand_lck (line 628) | static int mhvtl_queuecommand_lck(struct scsi_cmnd *SCpnt) {
  function mhvtl_queuecommand_lck (line 634) | static int mhvtl_queuecommand_lck(struct scsi_cmnd *SCpnt, done_funct_t ...
  function scsi_get_tag_type (line 658) | static inline int scsi_get_tag_type(struct scsi_device *sdev) {
  type scsi_device (line 676) | struct scsi_device
  function mhvtl_change_queue_depth (line 678) | static int mhvtl_change_queue_depth(struct scsi_device *sdev, int qdepth,
  type mhvtl_queued_cmd (line 698) | struct mhvtl_queued_cmd
  type mhvtl_lu_info (line 698) | struct mhvtl_lu_info
  type mhvtl_queued_cmd (line 701) | struct mhvtl_queued_cmd
  type scsi_device (line 718) | struct scsi_device
  function mhvtl_b_ioctl (line 720) | static int mhvtl_b_ioctl(struct scsi_device *sdp, int cmd, void __user *...
  function mhvtl_resp_report_luns (line 730) | static int mhvtl_resp_report_luns(struct scsi_cmnd *scp, struct mhvtl_lu...
  function __mhvtl_remove_sqcp (line 762) | static void __mhvtl_remove_sqcp(struct mhvtl_queued_cmd *sqcp) {
  function mhvtl_remove_sqcp (line 767) | static void mhvtl_remove_sqcp(struct mhvtl_lu_info *lu, struct mhvtl_que...
  type timer_list (line 776) | struct timer_list
  type mhvtl_queued_cmd (line 777) | struct mhvtl_queued_cmd
  function mhvtl_timer_intr_handler (line 780) | static void mhvtl_timer_intr_handler(unsigned long indx) {
  function mhvtl_sdev_alloc (line 814) | static int mhvtl_sdev_alloc(struct scsi_device *sdp) {
  type scsi_device (line 843) | struct scsi_device
  type queue_limits (line 843) | struct queue_limits
  function mhvtl_sdev_configure (line 845) | static int mhvtl_sdev_configure(struct scsi_device *sdp)
  function mhvtl_sdev_destroy (line 867) | static void mhvtl_sdev_destroy(struct scsi_device *sdp) {
  type mhvtl_lu_info (line 882) | struct mhvtl_lu_info
  type scsi_device (line 882) | struct scsi_device
  type mhvtl_hba_info (line 883) | struct mhvtl_hba_info
  type mhvtl_lu_info (line 884) | struct mhvtl_lu_info
  type mhvtl_lu_info (line 884) | struct mhvtl_lu_info
  type mhvtl_hba_info (line 889) | struct mhvtl_hba_info
  function mk_sense_buffer (line 905) | static void mk_sense_buffer(struct mhvtl_lu_info *lu, int key, int asc, ...
  function mhvtl_device_reset (line 918) | static int mhvtl_device_reset(struct scsi_cmnd *SCpnt) {
  function mhvtl_bus_reset (line 931) | static int mhvtl_bus_reset(struct scsi_cmnd *SCpnt) {
  function mhvtl_host_reset (line 950) | static int mhvtl_host_reset(struct scsi_cmnd *SCpnt) {
  function mhvtl_stop_queued_cmnd (line 967) | static int mhvtl_stop_queued_cmnd(struct scsi_cmnd *SCpnt) {
  function mhvtl_stop_all_queued (line 991) | static void mhvtl_stop_all_queued(void) {
  function mhvtl_abort (line 1016) | static int mhvtl_abort(struct scsi_cmnd *SCpnt) {
  type scsi_device (line 1025) | struct scsi_device
  type Scsi_Host (line 1025) | struct Scsi_Host
  function mhvtl_add_device (line 1037) | static int mhvtl_add_device(unsigned int minor, struct mhvtl_ctl *ctl) {
  type Scsi_Host (line 1123) | struct Scsi_Host
  function opts_show (line 1131) | static ssize_t opts_show(struct device_driver *ddp, char *buf) {
  type device_driver (line 1135) | struct device_driver
  function major_show (line 1160) | static ssize_t major_show(struct device_driver *ddp, char *buf) {
  function add_lu_store (line 1164) | static ssize_t add_lu_store(struct device_driver *ddp,
  function do_create_driverfs_files (line 1198) | static int do_create_driverfs_files(void) {
  function do_remove_driverfs_files (line 1206) | static void do_remove_driverfs_files(void) {
  function mhvtl_init (line 1212) | static int __init mhvtl_init(void) {
  function mhvtl_exit (line 1303) | static void __exit mhvtl_exit(void) {
  function mhvtl_pseudo_release (line 1326) | static void mhvtl_pseudo_release(struct device *dev) {
  type device (line 1330) | struct device
  function mhvtl_lld_bus_match (line 1339) | static int mhvtl_lld_bus_match(struct device *dev,
  type bus_type (line 1347) | struct bus_type
  function mhvtl_release_adapter (line 1352) | static void mhvtl_release_adapter(struct device *dev) {
  function mhvtl_add_adapter (line 1363) | static int mhvtl_add_adapter(void) {
  function mhvtl_remove_adapter (line 1401) | static void mhvtl_remove_adapter(void) {
  function mhvtl_driver_probe (line 1419) | static int mhvtl_driver_probe(struct device *dev) {
  function mhvtl_driver_remove (line 1452) | static int mhvtl_driver_remove(struct device *dev) {
  function mhvtl_get_user_data (line 1483) | static int mhvtl_get_user_data(unsigned int minor, char __user *arg) {
  function mhvtl_put_user_data (line 1519) | static int mhvtl_put_user_data(unsigned int minor, char __user *arg) {
  function send_mhvtl_header (line 1580) | static int send_mhvtl_header(unsigned int minor, char __user *arg) {
  function mhvtl_remove_lu (line 1615) | static int mhvtl_remove_lu(unsigned int minor, char __user *arg) {
  function mhvtl_c_ioctl (line 1675) | static long mhvtl_c_ioctl(struct file *file, unsigned int cmd, unsigned ...
  function mhvtl_c_ioctl_bkl (line 1702) | static int mhvtl_c_ioctl_bkl(struct inode *inode, struct file *file,
  function mhvtl_release (line 1746) | static int mhvtl_release(struct inode *inode, struct file *filp) {
  function mhvtl_open (line 1753) | static int mhvtl_open(struct inode *inode, struct file *filp) {

FILE: tcopy/tcopy.c
  function main (line 79) | int main(int argc, char *argv[])
  function verify (line 234) | void verify(register int inp, register int outp, register char *outb)
  function intr (line 287) | void intr(int signo)
  function writeop (line 309) | void writeop(int fd, int type)
  function usage (line 319) | static void usage(void)

FILE: usr/cmd/dump_messageQ.c
  function usage (line 36) | static void usage(char *prog) {
  function main (line 44) | int main(int argc, char **argv) {

FILE: usr/cmd/edit_tape.c
  function usage (line 50) | void usage(char *progname) {
  function main (line 73) | int main(int argc, char *argv[]) {

FILE: usr/cmd/mhvtl-device-conf-generator.c
  type vtl_info (line 31) | struct vtl_info {
  type vtl_info (line 36) | struct vtl_info
  type vtl_info (line 37) | struct vtl_info
  type vtl_info (line 39) | struct vtl_info
  type vtl_info (line 40) | struct vtl_info
  function pr_klog (line 52) | __attribute__((__format__(__printf__, 2, 3))) static void pr_klog(int le...
  function is_writable_dir (line 86) | static int is_writable_dir(char *path) {
  function add_to_libraries (line 145) | static int add_to_libraries(int lib_num) {
  function add_to_tapes (line 175) | static int add_to_tapes(int tape_num) {
  function parse_config_file (line 210) | static int parse_config_file(char *path) {
  function main (line 254) | int main(int argc, char **argv) {

FILE: usr/cmd/mktape.c
  function usage (line 26) | static void usage(char *progname) {
  function gettime (line 56) | int gettime() {
  function main (line 64) | int main(int argc, char *argv[]) {

FILE: usr/cmd/tape_util.c
  function print_mam_info (line 50) | static void print_mam_info(void) {
  function init_lunit (line 106) | static void init_lunit(struct lu_phy_attr *lu, struct priv_lu_ssc *priv_...
  function init_lu_ssc (line 121) | static void init_lu_ssc(struct priv_lu_ssc *lu_priv) {
  function check_restrictions (line 155) | uint8_t check_restrictions(struct scsi_cmd *cmd) {
  function valid_encryption_blk (line 162) | uint8_t valid_encryption_blk(struct scsi_cmd *cmd) {
  function register_ops (line 168) | void register_ops(struct lu_phy_attr *lu, int op, void *f, void *g, void...
  function ssc_personality_module_register (line 173) | void ssc_personality_module_register(struct ssc_personality_template *pm) {
  type media_details (line 181) | struct media_details
  type list_head (line 181) | struct list_head
  type media_details (line 182) | struct media_details
  function lookup_media_int (line 199) | static int lookup_media_int(struct name_to_media_info *media_info, char ...
  function add_drive_media_list (line 214) | int add_drive_media_list(struct lu_phy_attr *lu, int status, char *s) {
  function set_compression (line 255) | static void set_compression(struct priv_lu_ssc *lu_priv, char *compressi...
  function write_tape (line 271) | static int write_tape(char *source_file, uint32_t block_size, char *comp...
  function read_data (line 349) | static int read_data(uint8_t *sam_stat) {
  function usage (line 381) | static void usage(char *errmsg) {
  function dump_tape_metadata (line 405) | static void dump_tape_metadata(int dump_data, uint8_t *sam_stat) {
  function main (line 434) | int main(int argc, char *argv[]) {

FILE: usr/cmd/tapeexerciser.c
  function space_forward_filemark (line 13) | static int space_forward_filemark(int fd, int count) {
  function space_back_filemark (line 27) | static int space_back_filemark(int fd, int count) {
  function space_forward_block (line 41) | static int space_forward_block(int fd, int count) {
  function write_filemarks (line 55) | static int write_filemarks(int fd, int count) {
  function space_back_block (line 69) | static int space_back_block(int fd, int count) {
  function set_compression (line 83) | static int set_compression(int fd, int state) {
  function rewind_tape (line 97) | static int rewind_tape(int fd) {
  function read_block_position (line 111) | static int read_block_position(int fd) {
  function read_block (line 124) | static int read_block(int fd, int size) {
  function write_block (line 141) | static int write_block(int fd, int size) {
  function usage (line 160) | static void usage(char *arg) {
  function write_tape_pattern_1 (line 165) | void write_tape_pattern_1(int fd) {
  function write_tape_pattern_2 (line 180) | void write_tape_pattern_2(int fd) {
  function read_test_1 (line 196) | int read_test_1(int fd) {
  function read_test_2 (line 211) | int read_test_2(int fd) {
  function read_test_3 (line 235) | int read_test_3(int fd) {
  function read_test_4 (line 255) | int read_test_4(int fd) {
  function read_test_5 (line 282) | int read_test_5(int fd) {
  function main (line 304) | int main(int argc, char *argv[]) {

FILE: usr/cmd/vtlcmd.c
  function usage (line 56) | static void usage(char *prog) {
  function check_media (line 93) | int check_media(int libno, char *barcode) {
  function DisplayResponse (line 115) | void DisplayResponse(int msqid, char *s) {
  function ishex (line 122) | int ishex(char *str) {
  function isnumeric (line 131) | int isnumeric(char *str) {
  function PrintErrorExit (line 140) | void PrintErrorExit(char *prog, char *s) {
  function Check_TapeAlert (line 146) | void Check_TapeAlert(int argc, char **argv) {
  function Check_Load (line 160) | void Check_Load(int argc, char **argv) {
  function Check_delay (line 177) | void Check_delay(int argc, char **argv) {
  function Check_Unload (line 189) | void Check_Unload(int argc, char **argv) {
  function Check_Compression (line 199) | void Check_Compression(int argc, char **argv) {
  function Check_append_only (line 209) | void Check_append_only(int argc, char **argv) {
  function Check_List (line 219) | void Check_List(int argc, char **argv) {
  function Check_Empty (line 226) | void Check_Empty(int argc, char **argv) {
  function Check_Open (line 237) | void Check_Open(int argc, char **argv) {
  function Check_Close (line 248) | void Check_Close(int argc, char **argv) {
  function Check_Params (line 259) | void Check_Params(int argc, char **argv) {
  function CreateNewQueue (line 357) | int CreateNewQueue(void) {
  function OpenExistingQueue (line 370) | int OpenExistingQueue(key_t key) {
  function SendMsg (line 382) | int SendMsg(long ReceiverQid, long ReceiverMtyp, char *sndbuf) {
  function main (line 397) | int main(int argc, char **argv) {

FILE: usr/cmd/vtllibrary.c
  type smc_priv (line 76) | struct smc_priv
  type s_info (line 78) | struct s_info
  type lu_phy_attr (line 78) | struct lu_phy_attr
  function usage (line 80) | static void usage(char *progname) {
  type device_type_template (line 95) | struct device_type_template
  function smc_init (line 147) | __attribute__((constructor)) static void smc_init(void) {
  function register_ops (line 154) | void register_ops(struct lu_phy_attr *lu, int op,
  function processCommand (line 173) | static void processCommand(int cdev, uint8_t *cdb, struct mhvtl_ds *dbuf_p,
  function list_map (line 224) | static void list_map(struct q_msg *msg) {
  function already_in_slot (line 244) | int already_in_slot(char *barcode) {
  type s_info (line 265) | struct s_info
  type s_info (line 266) | struct s_info
  type list_head (line 267) | struct list_head
  type m_info (line 277) | struct m_info
  type lu_phy_attr (line 277) | struct lu_phy_attr
  type list_head (line 278) | struct list_head
  type m_info (line 279) | struct m_info
  type smc_priv (line 282) | struct smc_priv
  type m_info (line 296) | struct m_info
  type lu_phy_attr (line 296) | struct lu_phy_attr
  type list_head (line 297) | struct list_head
  type m_info (line 298) | struct m_info
  type m_info (line 310) | struct m_info
  type smc_priv (line 317) | struct smc_priv
  type m_info (line 319) | struct m_info
  function load_map (line 335) | static int load_map(struct q_msg *msg) {
  function open_map (line 400) | static void open_map(struct q_msg *msg) {
  function close_map (line 409) | static void close_map(struct q_msg *msg) {
  function add_storage_slot (line 419) | static void add_storage_slot(struct q_msg *msg) {
  function empty_map (line 456) | static int empty_map(struct q_msg *msg) {
  function set_access_bit (line 482) | static int set_access_bit(struct q_msg *msg) {
  function processMessageQ (line 500) | static int processMessageQ(struct q_msg *msg) {
  type d_info (line 555) | struct d_info
  type lu_phy_attr (line 555) | struct lu_phy_attr
  type list_head (line 556) | struct list_head
  type d_info (line 557) | struct d_info
  type smc_priv (line 560) | struct smc_priv
  type smc_priv (line 561) | struct smc_priv
  type s_info (line 576) | struct s_info
  type lu_phy_attr (line 576) | struct lu_phy_attr
  type s_info (line 577) | struct s_info
  type list_head (line 578) | struct list_head
  type smc_priv (line 580) | struct smc_priv
  type s_info (line 582) | struct s_info
  function update_drive_details (line 594) | static void update_drive_details(struct lu_phy_attr *lu) {
  function check_overflow (line 698) | static int check_overflow(struct lu_phy_attr *lu, int slot, char type) {
  function init_drive_slot (line 788) | void init_drive_slot(struct lu_phy_attr *lu, int slt, char *s) {
  function init_map_slot (line 820) | void init_map_slot(struct lu_phy_attr *lu, int slt, char *barcode) {
  function init_transport_slot (line 842) | void init_transport_slot(struct lu_phy_attr *lu, int slt, char *barcode) {
  function init_storage_slot (line 863) | void init_storage_slot(struct lu_phy_attr *lu, int slt, char *barcode) {
  function __init_slot_info (line 883) | static void __init_slot_info(struct lu_phy_attr *lu, int type) {
  function init_slot_info (line 1012) | void init_slot_info(struct lu_phy_attr *lu) {
  type s_info (line 1024) | struct s_info
  type s_info (line 1024) | struct s_info
  type list_head (line 1025) | struct list_head
  type s_info (line 1026) | struct s_info
  type s_info (line 1042) | struct s_info
  type s_info (line 1042) | struct s_info
  type list_head (line 1043) | struct list_head
  type s_info (line 1044) | struct s_info
  function save_config (line 1056) | static void save_config(struct lu_phy_attr *lu) {
  function init_lu (line 1153) | static int init_lu(struct lu_phy_attr *lu, unsigned minor, struct mhvtl_...
  function process_cmd (line 1339) | static void process_cmd(int cdev, uint8_t *buf, struct mhvtl_header *mhv...
  function cleanup_lu (line 1370) | static void cleanup_lu(struct lu_phy_attr *lu) {
  function customise_ibm_lu (line 1414) | static void customise_ibm_lu(struct lu_phy_attr *lu) {
  function customise_stk_lu (line 1423) | static void customise_stk_lu(struct lu_phy_attr *lu) {
  function customise_hp_lu (line 1436) | static void customise_hp_lu(struct lu_phy_attr *lu) {
  function customise_spectra_lu (line 1443) | static void customise_spectra_lu(struct lu_phy_attr *lu) {
  function customise_lu (line 1454) | static void customise_lu(struct lu_phy_attr *lu) {
  function rereadconfig (line 1473) | void rereadconfig(int sig) {
  function smc_personality_module_register (line 1521) | void smc_personality_module_register(struct smc_personality_template *pm) {
  function caught_signal (line 1526) | static void caught_signal(int signo) {
  function main (line 1539) | int main(int argc, char *argv[]) {

FILE: usr/cmd/vtltape.c
  type encryption (line 88) | struct encryption
  type tape_drives_table (line 131) | struct tape_drives_table {
  type lu_phy_attr (line 198) | struct lu_phy_attr
  function usage (line 200) | static void usage(char *progname) {
  function lookup_media_int (line 211) | static int lookup_media_int(struct name_to_media_info *media_info, char ...
  type name_to_media_info (line 225) | struct name_to_media_info
  type name_to_media_info (line 239) | struct name_to_media_info
  function lookup_mode_media_type (line 252) | int lookup_mode_media_type(struct name_to_media_info *media_info, int me...
  function finish_mount (line 269) | static void finish_mount(int sig) {
  function set_mount_timer (line 275) | static void set_mount_timer(int t) {
  function delay_opcode (line 281) | void delay_opcode(int what, int value) {
  function resp_report_density (line 305) | int resp_report_density(struct priv_lu_ssc *lu_priv, uint8_t media,
  function resp_read_attribute (line 390) | int resp_read_attribute(struct scsi_cmd *cmd) {
  function resp_write_attribute (line 465) | int resp_write_attribute(struct scsi_cmd *cmd) {
  function resp_space (line 528) | void resp_space(int64_t count, int code, uint8_t *sam_stat) {
  function resp_spin_page_0 (line 608) | static int resp_spin_page_0(uint8_t *buf, uint16_t sps, uint32_t alloc_l...
  function resp_spin_page_20 (line 646) | static int resp_spin_page_20(struct scsi_cmd *cmd) {
  function resp_spin (line 807) | uint8_t resp_spin(struct scsi_cmd *cmd) {
  function resp_spout (line 850) | uint8_t resp_spout(struct scsi_cmd *cmd) {
  function updateMAM (line 953) | static void updateMAM(uint8_t *sam_stat, int load) {
  function processCommand (line 1008) | static void processCommand(int cdev, uint8_t *cdb, struct mhvtl_ds *dbuf_p,
  type media_details (line 1071) | struct media_details
  type list_head (line 1071) | struct list_head
  type media_details (line 1072) | struct media_details
  function loadTape (line 1095) | int loadTape(char *PCL, uint8_t *sam_stat) {
  function dump_linked_list (line 1329) | static void dump_linked_list(void) {
  function unloadTape (line 1367) | void unloadTape(int update_library, uint8_t *sam_stat) {
  function processMessageQ (line 1394) | static int processMessageQ(struct q_msg *msg, uint8_t *sam_stat) {
  function config_lu (line 1646) | static void config_lu(struct lu_phy_attr *lu) {
  function cleanup_drive_media_list (line 1685) | static void cleanup_drive_media_list(struct lu_phy_attr *lu) {
  function add_drive_media_list (line 1699) | int add_drive_media_list(struct lu_phy_attr *lu, int status, char *s) {
  type device_type_template (line 1735) | struct device_type_template
  function register_ops (line 1809) | void register_ops(struct lu_phy_attr *lu, int op,
  function init_lu (line 1817) | static int init_lu(struct lu_phy_attr *lu, unsigned minor, struct mhvtl_...
  function process_cmd (line 2018) | static void process_cmd(int cdev, uint8_t *buf, struct mhvtl_header *mhv...
  function init_lu_ssc (line 2046) | static void init_lu_ssc(struct priv_lu_ssc *lu_priv) {
  function cleanup_lu (line 2082) | static void cleanup_lu(struct lu_phy_attr *lu) {
  function ssc_personality_module_register (line 2104) | void ssc_personality_module_register(struct ssc_personality_template *pm) {
  function caught_signal (line 2122) | static void caught_signal(int signo) {
  function main (line 2131) | int main(int argc, char *argv[]) {

FILE: usr/mhvtl_io.c
  function mk_sense_short_block (line 31) | static void
  function uncompress_lzo_block (line 46) | static int uncompress_lzo_block(uint8_t *buf, uint32_t tgtsize, uint8_t ...
  function uncompress_zlib_block (line 150) | static int uncompress_zlib_block(uint8_t *buf, uint32_t tgtsize, uint8_t...
  function mhvtl_crc32c (line 244) | static uint32_t mhvtl_crc32c(unsigned char const *buf, size_t size) {
  function readBlock (line 252) | int readBlock(uint8_t *buf, uint32_t request_sz, int sili, int lbp_metho...
  function lzo_uint (line 444) | static lzo_uint mhvtl_compressBound(lzo_uint src_sz) {
  function setup_crypto (line 452) | static void setup_crypto(struct scsi_cmd *cmd, struct priv_lu_ssc *lu_pr...
  function verify_lbp_crc (line 464) | static int32_t verify_lbp_crc(int lbp_method, unsigned char const *buf, ...
  function log_crc_options (line 498) | static void log_crc_options(int lbp_method, unsigned char const *buf, si...
  function log_lbp_method (line 520) | static void log_lbp_method(int lbp_method) {
  function writeBlock_nocomp (line 539) | static int writeBlock_nocomp(struct scsi_cmd *cmd, uint32_t src_sz, uint...
  function writeBlock_lzo (line 577) | static int writeBlock_lzo(struct scsi_cmd *cmd, uint32_t src_sz, uint8_t...
  function writeBlock_zlib (line 652) | static int writeBlock_zlib(struct scsi_cmd *cmd, uint32_t src_sz, uint8_...
  function writeBlock (line 721) | int writeBlock(struct scsi_cmd *cmd, uint32_t src_sz) {

FILE: usr/mhvtl_log.c
  type log_pg_list (line 74) | struct log_pg_list
  type list_head (line 74) | struct list_head
  type log_pg_list (line 75) | struct log_pg_list
  function alloc_log_page (line 99) | int alloc_log_page(struct lu_phy_attr *lu,
  function dealloc_all_log_pages (line 139) | void dealloc_all_log_pages(struct lu_phy_attr *lu) {
  function init_log_write_err_counter (line 150) | static void init_log_write_err_counter(void *log_ptr) {
  function add_log_write_err_counter (line 167) | int add_log_write_err_counter(struct lu_phy_attr *lu) {
  function init_log_read_err_counter (line 172) | static void init_log_read_err_counter(void *log_ptr) {
  function add_log_read_err_counter (line 189) | int add_log_read_err_counter(struct lu_phy_attr *lu) {
  function init_log_sequential_access (line 194) | static void init_log_sequential_access(void *log_ptr) {
  function add_log_sequential_access (line 213) | int add_log_sequential_access(struct lu_phy_attr *lu) {
  function init_log_temperature_page (line 218) | static void init_log_temperature_page(void *log_ptr) {
  function add_log_temperature_page (line 225) | int add_log_temperature_page(struct lu_phy_attr *lu) {
  function init_log_selftest_results (line 230) | static void init_log_selftest_results(void *log_ptr) {
  function add_log_selftest_results (line 256) | int add_log_selftest_results(struct lu_phy_attr *lu) {
  function init_log_volume_statistics (line 261) | static void init_log_volume_statistics(void *log_ptr) {
  function add_log_volume_statistics (line 319) | int add_log_volume_statistics(struct lu_phy_attr *lu) {
  function init_log_tape_alert (line 324) | static void init_log_tape_alert(void *log_ptr) {
  function add_log_tape_alert (line 333) | int add_log_tape_alert(struct lu_phy_attr *lu) {
  function init_log_tape_usage (line 338) | static void init_log_tape_usage(void *log_ptr) {
  function add_log_tape_usage (line 355) | int add_log_tape_usage(struct lu_phy_attr *lu) {
  function init_log_device_status (line 360) | static void init_log_device_status(void *log_ptr) {
  function add_log_device_status (line 367) | int add_log_device_status(struct lu_phy_attr *lu) {
  type DeviceStatus_pg (line 372) | struct DeviceStatus_pg
  type log_pg_list (line 373) | struct log_pg_list
  type DeviceStatus_pg (line 379) | struct DeviceStatus_pg
  function init_log_tape_capacity (line 382) | static void init_log_tape_capacity(void *log_ptr) {
  function add_log_tape_capacity (line 392) | int add_log_tape_capacity(struct lu_phy_attr *lu) {
  function init_log_data_compression (line 397) | static void init_log_data_compression(void *log_ptr) {
  function add_log_data_compression (line 413) | int add_log_data_compression(struct lu_phy_attr *lu) {
  function init_log_performance_characteristics (line 418) | static void init_log_performance_characteristics(void *log_ptr) {
  function add_log_performance_characteristics (line 425) | int add_log_performance_characteristics(struct lu_phy_attr *lu) {
  function set_lp_11_macc (line 431) | void set_lp_11_macc(int flag) {
  function set_lp11_compression (line 437) | void set_lp11_compression(int flag) {
  function set_lp_11_crqst (line 443) | void set_lp_11_crqst(int flag) {
  function set_lp_11_crqrd (line 449) | void set_lp_11_crqrd(int flag) {
  function set_lp_11_wp (line 456) | void set_lp_11_wp(int flag) {
  function set_lp11_medium_present (line 462) | void set_lp11_medium_present(int flag) {
  function update_VolumeStatistics (line 492) | void update_VolumeStatistics(struct VolumeStatistics_pg *pg, struct priv...
  function update_TapeAlert (line 560) | int update_TapeAlert(uint64_t flags) {
  function set_TapeAlert (line 589) | int set_TapeAlert(uint64_t flags) {
  function update_TapeUsage (line 641) | void update_TapeUsage(struct TapeUsage_pg *b) {
  function update_TapeCapacity (line 659) | void update_TapeCapacity(struct TapeCapacity_pg *pg) {
  function update_SequentialAccessDevice (line 677) | void update_SequentialAccessDevice(struct SequentialAccessDevice_pg *sa) {
  function set_current_state (line 705) | void set_current_state(int s) {
  function get_tape_load_status (line 764) | int get_tape_load_status(void) {
  function set_tape_load_status (line 768) | void set_tape_load_status(int s) {

FILE: usr/mode.c
  type mode (line 63) | struct mode
  type list_head (line 63) | struct list_head
  type mode (line 64) | struct mode
  type mode (line 90) | struct mode
  type list_head (line 90) | struct list_head
  type mode (line 92) | struct mode
  type mode (line 99) | struct mode
  type mode (line 99) | struct mode
  function dealloc_all_mode_pages (line 126) | void dealloc_all_mode_pages(struct lu_phy_attr *lu) {
  function add_mode_page_rw_err_recovery (line 142) | int add_mode_page_rw_err_recovery(struct lu_phy_attr *lu) {
  function add_mode_disconnect_reconnect (line 178) | int add_mode_disconnect_reconnect(struct lu_phy_attr *lu) {
  function add_mode_control (line 217) | int add_mode_control(struct lu_phy_attr *lu) {
  function add_mode_control_extension (line 252) | int add_mode_control_extension(struct lu_phy_attr *lu) {
  function add_mode_control_data_protection (line 289) | int add_mode_control_data_protection(struct lu_phy_attr *lu) {
  function add_mode_data_compression (line 341) | int add_mode_data_compression(struct lu_phy_attr *lu) {
  function set_mode_compression (line 383) | void set_mode_compression(struct scsi_cmd *cmd, uint8_t *p) {
  function add_mode_device_configuration (line 424) | int add_mode_device_configuration(struct lu_phy_attr *lu) {
  function set_device_configuration (line 472) | void set_device_configuration(struct scsi_cmd *cmd, uint8_t *p) {
  function add_mode_device_configuration_extension (line 501) | int add_mode_device_configuration_extension(struct lu_phy_attr *lu) {
  function set_device_configuration_extension (line 554) | uint8_t set_device_configuration_extension(struct scsi_cmd *cmd, uint8_t...
  function add_mode_medium_partition (line 630) | int add_mode_medium_partition(struct lu_phy_attr *lu) {
  function set_medium_partition (line 688) | void set_medium_partition(struct scsi_cmd *cmd, uint8_t *p) {
  function add_mode_power_condition (line 707) | int add_mode_power_condition(struct lu_phy_attr *lu) {
  function add_mode_information_exception (line 738) | int add_mode_information_exception(struct lu_phy_attr *lu) {
  function add_mode_medium_configuration (line 772) | int add_mode_medium_configuration(struct lu_phy_attr *lu) {
  function add_mode_ult_encr_mode_pages (line 814) | int add_mode_ult_encr_mode_pages(struct lu_phy_attr *lu) {
  function add_mode_vendor_25h_mode_pages (line 859) | int add_mode_vendor_25h_mode_pages(struct lu_phy_attr *lu) {
  function add_mode_encryption_mode_attribute (line 897) | int add_mode_encryption_mode_attribute(struct lu_phy_attr *lu) {
  function add_mode_ait_device_configuration (line 934) | int add_mode_ait_device_configuration(struct lu_phy_attr *lu) {
  function add_mode_element_address_assignment (line 969) | int add_mode_element_address_assignment(struct lu_phy_attr *lu) {
  function add_mode_transport_geometry (line 1018) | int add_mode_transport_geometry(struct lu_phy_attr *lu) {
  function add_mode_device_capabilities (line 1053) | int add_mode_device_capabilities(struct lu_phy_attr *lu) {
  function add_mode_behavior_configuration (line 1101) | int add_mode_behavior_configuration(struct lu_phy_attr *lu) {
  function update_prog_early_warning (line 1135) | int update_prog_early_warning(struct lu_phy_attr *lu) {
  function update_logical_block_protection (line 1157) | int update_logical_block_protection(struct lu_phy_attr *lu, uint8_t *buf) {
  function set_lbp (line 1191) | uint8_t set_lbp(struct scsi_cmd *cmd, uint8_t *buf, int len) {
  function add_smc_mode_page_drive_configuration (line 1207) | int add_smc_mode_page_drive_configuration(struct lu_phy_attr *lu) {

FILE: usr/pm/ait_pm.c
  type density_info (line 39) | struct density_info
  type density_info (line 43) | struct density_info
  type density_info (line 47) | struct density_info
  type density_info (line 51) | struct density_info
  type name_to_media_info (line 55) | struct name_to_media_info
  function clear_ait_WORM (line 77) | static uint8_t clear_ait_WORM(struct list_head *l) {
  function set_ait_WORM (line 92) | static uint8_t set_ait_WORM(struct list_head *l) {
  function clear_ait_compression (line 107) | static uint8_t clear_ait_compression(struct list_head *l) {
  function set_ait_compression (line 113) | static uint8_t set_ait_compression(struct list_head *l, int lvl) {
  function update_ait_encryption_mode (line 119) | static uint8_t update_ait_encryption_mode(struct list_head *m, void *p, ...
  function encr_capabilities_ait (line 128) | static int encr_capabilities_ait(struct scsi_cmd *cmd) {
  function init_ait_inquiry (line 168) | static void init_ait_inquiry(struct lu_phy_attr *lu) {
  function ait_kad_validation (line 225) | static int ait_kad_validation(int mode, int ukad, int akad) {
  function set_cleaning_timer (line 257) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 263) | static void inc_cleaning_state(int sig) {
  function ait_cleaning (line 273) | static uint8_t ait_cleaning(void *ssc_priv) {
  function init_ait_mode_pages (line 291) | static void init_ait_mode_pages(struct lu_phy_attr *lu) {
  function ait_media_load (line 302) | static uint8_t ait_media_load(struct lu_phy_attr *lu, int load) {
  type ssc_personality_template (line 325) | struct ssc_personality_template
  function init_ait1_ssc (line 338) | void init_ait1_ssc(struct lu_phy_attr *lu) {
  function init_ait2_ssc (line 375) | void init_ait2_ssc(struct lu_phy_attr *lu) {
  function init_ait3_ssc (line 416) | void init_ait3_ssc(struct lu_phy_attr *lu) {
  function init_ait4_ssc (line 460) | void init_ait4_ssc(struct lu_phy_attr *lu) {

FILE: usr/pm/default_smc_pm.c
  type smc_personality_template (line 11) | struct smc_personality_template
  function update_default_inquiry (line 19) | static void update_default_inquiry(struct lu_phy_attr *lu) {
  function init_default_smc (line 41) | void init_default_smc(struct lu_phy_attr *lu) {

FILE: usr/pm/default_ssc_pm.c
  type density_info (line 39) | struct density_info
  type name_to_media_info (line 43) | struct name_to_media_info
  function clear_default_comp (line 224) | static uint8_t clear_default_comp(struct list_head *l) {
  function set_default_comp (line 230) | static uint8_t set_default_comp(struct list_head *l, int lvl) {
  function update_default_encryption_mode (line 236) | static uint8_t update_default_encryption_mode(struct list_head *m, void ...
  function set_default_WORM (line 242) | static uint8_t set_default_WORM(struct list_head *l) {
  function clear_default_WORM (line 247) | static uint8_t clear_default_WORM(struct list_head *l) {
  function init_default_inquiry (line 252) | static void init_default_inquiry(struct lu_phy_attr *lu) {
  function default_kad_validation (line 309) | static int default_kad_validation(int mode, int ukad, int akad) {
  function set_cleaning_timer (line 341) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 347) | static void inc_cleaning_state(int sig) {
  function default_media_load (line 357) | static uint8_t default_media_load(struct lu_phy_attr *lu, int load) {
  function default_cleaning (line 362) | static uint8_t default_cleaning(void *ssc_priv) {
  function init_default_mode_pages (line 377) | static void init_default_mode_pages(struct lu_phy_attr *lu) {
  type ssc_personality_template (line 391) | struct ssc_personality_template
  function init_default_ssc (line 405) | void init_default_ssc(struct lu_phy_attr *lu) {

FILE: usr/pm/hp_smc_pm.c
  function update_eml_vpd_80 (line 11) | static void update_eml_vpd_80(struct lu_phy_attr *lu) {
  function update_eml_vpd_83 (line 30) | static void update_eml_vpd_83(struct lu_phy_attr *lu) {
  type smc_personality_template (line 97) | struct smc_personality_template
  function init_hp_eml_smc (line 109) | void init_hp_eml_smc(struct lu_phy_attr *lu) {
  function init_hp_msl_smc (line 123) | void init_hp_msl_smc(struct lu_phy_attr *lu) {

FILE: usr/pm/hp_ultrium_pm.c
  type density_info (line 39) | struct density_info
  type density_info (line 42) | struct density_info
  type density_info (line 45) | struct density_info
  type density_info (line 48) | struct density_info
  type density_info (line 51) | struct density_info
  type density_info (line 54) | struct density_info
  type density_info (line 57) | struct density_info
  type density_info (line 60) | struct density_info
  type name_to_media_info (line 64) | struct name_to_media_info
  function clear_ult_compression (line 112) | static uint8_t clear_ult_compression(struct list_head *m) {
  function set_ult_compression (line 118) | static uint8_t set_ult_compression(struct list_head *m, int lvl) {
  function set_ult_WORM (line 124) | static uint8_t set_ult_WORM(struct list_head *lst) {
  function clear_ult_WORM (line 148) | static uint8_t clear_ult_WORM(struct list_head *m) {
  function update_ult_encryption_mode (line 153) | static uint8_t update_ult_encryption_mode(struct list_head *m, void *p, ...
  function encr_capabilities_ult (line 168) | static int encr_capabilities_ult(struct scsi_cmd *cmd) {
  function update_hp_vpd_cx (line 236) | static void update_hp_vpd_cx(struct lu_phy_attr *lu, uint8_t pg, char *c...
  function init_ult_inquiry (line 255) | static void init_ult_inquiry(struct lu_phy_attr *lu) {
  function hp_lto_kad_validation (line 363) | static int hp_lto_kad_validation(int encrypt_mode, int ukad, int akad) {
  function set_cleaning_timer (line 401) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 407) | static void inc_cleaning_state(int sig) {
  function hp_media_load (line 417) | static uint8_t hp_media_load(struct lu_phy_attr *lu, int load) {
  function hp_cleaning (line 433) | static uint8_t hp_cleaning(void *ssc_priv) {
  type ssc_personality_template (line 457) | struct ssc_personality_template
  function init_hp_ult_1 (line 467) | void init_hp_ult_1(struct lu_phy_attr *lu) {
  function init_hp_ult_2 (line 513) | void init_hp_ult_2(struct lu_phy_attr *lu) {
  function init_hp_ult_3 (line 563) | void init_hp_ult_3(struct lu_phy_attr *lu) {
  function init_hp_ult_4 (line 621) | void init_hp_ult_4(struct lu_phy_attr *lu) {
  function init_hp_ult_5 (line 689) | void init_hp_ult_5(struct lu_phy_attr *lu) {
  function init_hp_ult_6 (line 762) | void init_hp_ult_6(struct lu_phy_attr *lu) {
  function init_hp_ult_7 (line 836) | void init_hp_ult_7(struct lu_phy_attr *lu) {
  function init_hp_ult_8 (line 909) | void init_hp_ult_8(struct lu_phy_attr *lu) {

FILE: usr/pm/ibm_03592_pm.c
  type density_info (line 41) | struct density_info
  type density_info (line 45) | struct density_info
  type density_info (line 49) | struct density_info
  type density_info (line 53) | struct density_info
  type name_to_media_info (line 57) | struct name_to_media_info
  function valid_encryption_media_E06 (line 88) | static uint8_t valid_encryption_media_E06(struct scsi_cmd *cmd) {
  function clear_3592_comp (line 161) | static uint8_t clear_3592_comp(struct list_head *m) {
  function set_3592_comp (line 167) | static uint8_t set_3592_comp(struct list_head *m, int lvl) {
  function update_3592_encryption_mode (line 173) | static uint8_t update_3592_encryption_mode(struct list_head *m, void *p,...
  function set_3592_WORM (line 179) | static uint8_t set_3592_WORM(struct list_head *m) {
  function clear_3592_WORM (line 184) | static uint8_t clear_3592_WORM(struct list_head *m) {
  function encr_capabilities_3592 (line 189) | static int encr_capabilities_3592(struct scsi_cmd *cmd) {
  function init_3592_inquiry (line 228) | static void init_3592_inquiry(struct lu_phy_attr *lu) {
  function e06_kad_validation (line 284) | static int e06_kad_validation(int encrypt_mode, int ukad, int akad) {
  function set_cleaning_timer (line 322) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 328) | static void inc_cleaning_state(int sig) {
  function ibm_media_load (line 338) | static uint8_t ibm_media_load(struct lu_phy_attr *lu, int load) {
  function ibm_cleaning (line 343) | static uint8_t ibm_cleaning(void *ssc_priv) {
  function init_03592_mode_pages (line 358) | static void init_03592_mode_pages(struct lu_phy_attr *lu) {
  type ssc_personality_template (line 375) | struct ssc_personality_template
  function init_3592_j1a (line 390) | void init_3592_j1a(struct lu_phy_attr *lu) {
  function init_3592_E05 (line 427) | void init_3592_E05(struct lu_phy_attr *lu) {
  function init_3592_E06 (line 467) | void init_3592_E06(struct lu_phy_attr *lu) {
  function init_3592_E07 (line 516) | void init_3592_E07(struct lu_phy_attr *lu) {

FILE: usr/pm/ibm_smc_pm.c
  type smc_personality_template (line 14) | struct smc_personality_template
  function update_ibm_3100_vpd_d0 (line 25) | static void update_ibm_3100_vpd_d0(struct lu_phy_attr *lu) {
  function update_ibm_3100_vpd_ff (line 74) | static void update_ibm_3100_vpd_ff(struct lu_phy_attr *lu) {
  function update_3573_device_capabilities (line 100) | static void update_3573_device_capabilities(struct lu_phy_attr *lu) {
  function update_3584_device_capabilities (line 123) | static void update_3584_device_capabilities(struct lu_phy_attr *lu) {
  function update_ibm_3584_vpd_80 (line 146) | static void update_ibm_3584_vpd_80(struct lu_phy_attr *lu) {
  function update_ibm_3584_vpd_83 (line 172) | static void update_ibm_3584_vpd_83(struct lu_phy_attr *lu) {
  function update_ibm_3584_inquiry (line 205) | static void update_ibm_3584_inquiry(struct lu_phy_attr *lu) {
  function update_ibm_3100_inquiry (line 215) | static void update_ibm_3100_inquiry(struct lu_phy_attr *lu) {
  function update_ibm_3100_vpd_80 (line 231) | static void update_ibm_3100_vpd_80(struct lu_phy_attr *lu) {
  function update_ibm_3100_vpd_83 (line 253) | static void update_ibm_3100_vpd_83(struct lu_phy_attr *lu) {
  function update_ibm_3100_vpd_c0 (line 282) | static void update_ibm_3100_vpd_c0(struct lu_phy_attr *lu) {
  function init_ibmts3100 (line 307) | void init_ibmts3100(struct lu_phy_attr *lu) {
  function init_ibm3584 (line 398) | void init_ibm3584(struct lu_phy_attr *lu) {

FILE: usr/pm/overland_pm.c
  function update_eml_vpd_80 (line 11) | static void update_eml_vpd_80(struct lu_phy_attr *lu) {
  function update_eml_vpd_83 (line 31) | static void update_eml_vpd_83(struct lu_phy_attr *lu) {
  type smc_personality_template (line 87) | struct smc_personality_template
  function init_overland_smc (line 99) | void init_overland_smc(struct lu_phy_attr *lu) {

FILE: usr/pm/quantum_dlt_pm.c
  type density_info (line 41) | struct density_info
  type density_info (line 44) | struct density_info
  type density_info (line 47) | struct density_info
  type density_info (line 50) | struct density_info
  type density_info (line 53) | struct density_info
  type density_info (line 56) | struct density_info
  type density_info (line 59) | struct density_info
  type name_to_media_info (line 63) | struct name_to_media_info
  function clear_dlt_compression (line 87) | static uint8_t clear_dlt_compression(struct list_head *m) {
  function set_dlt_compression (line 93) | static uint8_t set_dlt_compression(struct list_head *m, int lvl) {
  function update_vpd_dlt_c0 (line 102) | static void update_vpd_dlt_c0(struct lu_phy_attr *lu) {
  function get_product_family (line 122) | static int get_product_family(struct lu_phy_attr *lu) {
  function update_vpd_dlt_c1 (line 134) | static void update_vpd_dlt_c1(struct lu_phy_attr *lu, char *sn) {
  function set_dlt_WORM (line 148) | static uint8_t set_dlt_WORM(struct list_head *lst) {
  function clear_dlt_WORM (line 172) | static uint8_t clear_dlt_WORM(struct list_head *m) {
  function init_dlt_inquiry (line 178) | static void init_dlt_inquiry(struct lu_phy_attr *lu) {
  function init_sdlt_inquiry (line 218) | static void init_sdlt_inquiry(struct lu_phy_attr *lu) {
  function set_cleaning_timer (line 315) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 321) | static void inc_cleaning_state(int sig) {
  function dlt_media_load (line 331) | static uint8_t dlt_media_load(struct lu_phy_attr *lu, int load) {
  function dlt_cleaning (line 336) | static uint8_t dlt_cleaning(void *ssc_priv) {
  type ssc_personality_template (line 356) | struct ssc_personality_template
  function init_dlt7000_ssc (line 366) | void init_dlt7000_ssc(struct lu_phy_attr *lu) {
  function init_dlt8000_ssc (line 416) | void init_dlt8000_ssc(struct lu_phy_attr *lu) {
  function init_sdlt320_ssc (line 467) | void init_sdlt320_ssc(struct lu_phy_attr *lu) {
  function init_sdlt600_ssc (line 519) | void init_sdlt600_ssc(struct lu_phy_attr *lu) {

FILE: usr/pm/scalar_pm.c
  type smc_personality_template (line 11) | struct smc_personality_template
  function init_scalar_inquiry (line 19) | static void init_scalar_inquiry(struct lu_phy_attr *lu) {
  function update_scalar_vpd_80 (line 36) | static void update_scalar_vpd_80(struct lu_phy_attr *lu) {
  function update_scalar_vpd_83 (line 56) | static void update_scalar_vpd_83(struct lu_phy_attr *lu) {
  function init_scalar_smc (line 80) | void init_scalar_smc(struct lu_phy_attr *lu) {

FILE: usr/pm/spectra_pm.c
  function update_spectra_215_device_capabilities (line 10) | static void update_spectra_215_device_capabilities(struct lu_phy_attr *l...
  function update_spectra_gator_device_capabilities (line 27) | static void update_spectra_gator_device_capabilities(struct lu_phy_attr ...
  function update_spectra_t_series_device_capabilities (line 44) | static void update_spectra_t_series_device_capabilities(struct lu_phy_at...
  type smc_personality_template (line 61) | struct smc_personality_template
  function init_spectra_215_smc (line 78) | void init_spectra_215_smc(struct lu_phy_attr *lu) {
  function init_spectra_gator_smc (line 105) | void init_spectra_gator_smc(struct lu_phy_attr *lu) {
  function init_spectra_logic_smc (line 131) | void init_spectra_logic_smc(struct lu_phy_attr *lu) {

FILE: usr/pm/stk9x40_pm.c
  type density_info (line 40) | struct density_info
  type density_info (line 44) | struct density_info
  type density_info (line 48) | struct density_info
  type density_info (line 52) | struct density_info
  type density_info (line 56) | struct density_info
  type density_info (line 60) | struct density_info
  type name_to_media_info (line 64) | struct name_to_media_info
  function valid_encryption_blk_9840 (line 102) | uint8_t valid_encryption_blk_9840(struct scsi_cmd *cmd) {
  function clear_9840_comp (line 157) | static uint8_t clear_9840_comp(struct list_head *m) {
  function set_9840_comp (line 163) | static uint8_t set_9840_comp(struct list_head *m, int lvl) {
  function update_9840_encryption_mode (line 169) | static uint8_t update_9840_encryption_mode(struct list_head *m, void *p,...
  function set_9840_WORM (line 175) | static uint8_t set_9840_WORM(struct list_head *m) {
  function clear_9840_WORM (line 180) | static uint8_t clear_9840_WORM(struct list_head *m) {
  function encr_capabilities_9840 (line 185) | static int encr_capabilities_9840(struct scsi_cmd *cmd) {
  function T9840_kad_validation (line 225) | static int T9840_kad_validation(int encrypt_mode, int ukad, int akad) {
  function set_cleaning_timer (line 259) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 265) | static void inc_cleaning_state(int sig) {
  function T9840_media_load (line 275) | static uint8_t T9840_media_load(struct lu_phy_attr *lu, int load) {
  function T9840_cleaning (line 280) | static uint8_t T9840_cleaning(void *ssc_priv) {
  function init_9840_mode_pages (line 295) | static void init_9840_mode_pages(struct lu_phy_attr *lu) {
  type ssc_personality_template (line 310) | struct ssc_personality_template
  function init_9840_inquiry (line 326) | static void init_9840_inquiry(struct lu_phy_attr *lu) {
  function init_9840A_ssc (line 349) | void init_9840A_ssc(struct lu_phy_attr *lu) {
  function init_9840B_ssc (line 387) | void init_9840B_ssc(struct lu_phy_attr *lu) {
  function init_9840C_ssc (line 428) | void init_9840C_ssc(struct lu_phy_attr *lu) {
  function init_9840D_ssc (line 473) | void init_9840D_ssc(struct lu_phy_attr *lu) {
  function init_9940A_ssc (line 515) | void init_9940A_ssc(struct lu_phy_attr *lu) {
  function init_9940B_ssc (line 554) | void init_9940B_ssc(struct lu_phy_attr *lu) {

FILE: usr/pm/stklxx_pm.c
  type smc_personality_template (line 12) | struct smc_personality_template
  function update_stk_l_vpd_80 (line 20) | static void update_stk_l_vpd_80(struct lu_phy_attr *lu) {
  function update_stk_l_vpd_83 (line 43) | static void update_stk_l_vpd_83(struct lu_phy_attr *lu) {
  function init_stkl20 (line 55) | void init_stkl20(struct lu_phy_attr *lu) {
  function init_stklxx (line 80) | void init_stklxx(struct lu_phy_attr *lu) {
  function init_stkslxx (line 103) | void init_stkslxx(struct lu_phy_attr *lu) {

FILE: usr/pm/t10000_pm.c
  type density_info (line 41) | struct density_info
  type density_info (line 45) | struct density_info
  type density_info (line 49) | struct density_info
  type name_to_media_info (line 53) | struct name_to_media_info
  function valid_encryption_blk_t10k (line 84) | uint8_t valid_encryption_blk_t10k(struct scsi_cmd *cmd) {
  function clear_t10k_comp (line 139) | static uint8_t clear_t10k_comp(struct list_head *m) {
  function set_t10k_comp (line 145) | static uint8_t set_t10k_comp(struct list_head *m, int lvl) {
  function update_t10k_encryption_mode (line 151) | static uint8_t update_t10k_encryption_mode(struct list_head *m, void *p,...
  function set_t10k_WORM (line 157) | static uint8_t set_t10k_WORM(struct list_head *m) {
  function clear_t10k_WORM (line 162) | static uint8_t clear_t10k_WORM(struct list_head *m) {
  function encr_capabilities_t10k (line 167) | static int encr_capabilities_t10k(struct scsi_cmd *cmd) {
  function t10k_kad_validation (line 207) | static int t10k_kad_validation(int encrypt_mode, int ukad, int akad) {
  function set_cleaning_timer (line 241) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 247) | static void inc_cleaning_state(int sig) {
  function t10k_media_load (line 257) | static uint8_t t10k_media_load(struct lu_phy_attr *lu, int load) {
  function t10k_cleaning (line 292) | static uint8_t t10k_cleaning(void *ssc_priv) {
  function init_t10k_mode_pages (line 307) | static void init_t10k_mode_pages(struct lu_phy_attr *lu) {
  function t10k_init_sense (line 335) | static void t10k_init_sense(struct scsi_cmd *cmd) {
  function t10k_sense (line 365) | uint8_t t10k_sense(struct scsi_cmd *cmd) {
  type ssc_personality_template (line 374) | struct ssc_personality_template
  function init_t10k_inquiry (line 390) | static void init_t10k_inquiry(struct lu_phy_attr *lu) {
  function init_t10kA_ssc (line 431) | void init_t10kA_ssc(struct lu_phy_attr *lu) {
  function init_t10kB_ssc (line 470) | void init_t10kB_ssc(struct lu_phy_attr *lu) {
  function init_t10kC_ssc (line 512) | void init_t10kC_ssc(struct lu_phy_attr *lu) {

FILE: usr/pm/ult3580_pm.c
  type density_info (line 39) | struct density_info
  type density_info (line 42) | struct density_info
  type density_info (line 45) | struct density_info
  type density_info (line 48) | struct density_info
  type density_info (line 51) | struct density_info
  type density_info (line 54) | struct density_info
  type density_info (line 57) | struct density_info
  type density_info (line 60) | struct density_info
  type density_info (line 63) | struct density_info
  type name_to_media_info (line 67) | struct name_to_media_info
  function clear_ult_compression (line 121) | static uint8_t clear_ult_compression(struct list_head *m) {
  function set_ult_compression (line 127) | static uint8_t set_ult_compression(struct list_head *m, int lvl) {
  function update_vpd_ult_c0 (line 136) | static void update_vpd_ult_c0(struct lu_phy_attr *lu) {
  function update_vpd_ult_c1 (line 155) | static void update_vpd_ult_c1(struct lu_phy_attr *lu, char *sn) {
  function set_ult_WORM (line 168) | static uint8_t set_ult_WORM(struct list_head *lst) {
  function clear_ult_WORM (line 193) | static uint8_t clear_ult_WORM(struct list_head *m) {
  function update_ult_encryption_mode (line 198) | static uint8_t update_ult_encryption_mode(struct list_head *m, void *p, ...
  function encr_capabilities_ult (line 213) | static int encr_capabilities_ult(struct scsi_cmd *cmd) {
  function update_vpd_lbp (line 275) | static void update_vpd_lbp(struct lu_phy_attr *lu) {
  function init_ult_inquiry (line 302) | static void init_ult_inquiry(struct lu_phy_attr *lu) {
  function td4_kad_validation (line 384) | static int td4_kad_validation(int encrypt_mode, int ukad, int akad) {
  function set_cleaning_timer (line 422) | static void set_cleaning_timer(int t) {
  function inc_cleaning_state (line 428) | static void inc_cleaning_state(int sig) {
  function ult_media_load (line 438) | static uint8_t ult_media_load(struct lu_phy_attr *lu, int load) {
  function ult_cleaning (line 483) | static uint8_t ult_cleaning(void *ssc_priv) {
  type ssc_personality_template (line 508) | struct ssc_personality_template
  function init_ult3580_td1 (line 518) | void init_ult3580_td1(struct lu_phy_attr *lu) {
  function init_ult3580_td2 (line 566) | void init_ult3580_td2(struct lu_phy_attr *lu) {
  function init_ult3580_td3 (line 616) | void init_ult3580_td3(struct lu_phy_attr *lu) {
  function init_ult3580_td4 (line 675) | void init_ult3580_td4(struct lu_phy_attr *lu) {
  function init_ult3580_td5 (line 742) | void init_ult3580_td5(struct lu_phy_attr *lu) {
  function init_ult3580_td6 (line 817) | void init_ult3580_td6(struct lu_phy_attr *lu) {
  function init_ult3580_td7 (line 893) | void init_ult3580_td7(struct lu_phy_attr *lu) {
  function init_ult3580_td8 (line 969) | void init_ult3580_td8(struct lu_phy_attr *lu) {
  function init_ult3580_td9 (line 1046) | void init_ult3580_td9(struct lu_phy_attr *lu) {

FILE: usr/smc.c
  function smc_allow_removal (line 41) | uint8_t smc_allow_removal(struct scsi_cmd *cmd) {
  function smc_initialize_element_status (line 48) | uint8_t smc_initialize_element_status(struct scsi_cmd *cmd) {
  function smc_initialize_element_status_with_range (line 63) | uint8_t smc_initialize_element_status_with_range(struct scsi_cmd *cmd) {
  function slot_type (line 80) | static int slot_type(struct smc_priv *smc_p, int addr) {
  function slot_number (line 100) | static int slot_number(struct smc_personality_template *pm, struct s_inf...
  type s_info (line 117) | struct s_info
  type smc_priv (line 117) | struct smc_priv
  type list_head (line 118) | struct list_head
  type s_info (line 119) | struct s_info
  type d_info (line 136) | struct d_info
  type smc_priv (line 136) | struct smc_priv
  type s_info (line 137) | struct s_info
  function is_drive_empty (line 147) | static int is_drive_empty(struct d_info *drv) {
  function slotAccess (line 174) | int slotAccess(struct s_info *s) {
  function slotOccupied (line 179) | int slotOccupied(struct s_info *s) {
  function driveOccupied (line 184) | static int driveOccupied(struct d_info *d) {
  function check_tape_unload (line 193) | static int check_tape_unload(void) {
  function setAccessStatus (line 248) | void setAccessStatus(struct s_info *s, int flg) {
  function setImpExpStatus (line 274) | void setImpExpStatus(struct s_info *s, int flg) {
  function setFullStatus (line 284) | void setFullStatus(struct s_info *s, int flg) {
  function setSlotEmpty (line 291) | void setSlotEmpty(struct s_info *s) {
  function setDriveEmpty (line 295) | static void setDriveEmpty(struct d_info *d) {
  function setSlotFull (line 302) | void setSlotFull(struct s_info *s) {
  function setDriveFull (line 306) | void setDriveFull(struct d_info *d) {
  function is_map_slot (line 311) | static int is_map_slot(struct s_info *s) {
  function map_access_ok (line 317) | static int map_access_ok(struct smc_priv *smc_p, struct s_info *s) {
  function dump_element_desc (line 326) | static int dump_element_desc(uint8_t *p, int voltag, int num_elem, int len,
  function decode_element_status (line 369) | static void decode_element_status(struct smc_priv *smc_p, uint8_t *p) {
  function sizeof_element (line 423) | static int sizeof_element(struct scsi_cmd *cmd, int type) {
  function fill_ed (line 443) | static int fill_ed(struct scsi_cmd *cmd, uint8_t *p, struct s_info *s) {
  function fill_element_status_page_hdr (line 572) | static void fill_element_status_page_hdr(struct scsi_cmd *cmd, uint8_t *p,
  function fill_element_status_data_hdr (line 612) | static int fill_element_status_data_hdr(uint8_t *p, int start, int count,
  function find_first_matching_element (line 646) | static uint32_t find_first_matching_element(struct smc_priv *priv,
  function num_available_elements (line 667) | static uint32_t num_available_elements(struct smc_priv *priv, uint8_t type,
  function fill_element_page (line 706) | static uint32_t fill_element_page(struct scsi_cmd *cmd, uint8_t *p,
  function smc_read_element_status (line 797) | uint8_t smc_read_element_status(struct scsi_cmd *cmd) {
  function check_tape_load (line 969) | static int check_tape_load(void) {
  function move_cart (line 994) | static void move_cart(struct s_info *src, struct s_info *dest) {
  function run_move_command (line 1012) | static int run_move_command(struct smc_priv *smc_p, struct s_info *src,
  function move_slot2drive (line 1052) | static int move_slot2drive(struct smc_priv *smc_p,
  function move_slot2slot (line 1129) | static int move_slot2slot(struct smc_priv *smc_p, int src_addr,
  function valid_slot (line 1194) | static int valid_slot(struct smc_priv *smc_p, int addr) {
  function move_drive2slot (line 1223) | static int move_drive2slot(struct smc_priv *smc_p,
  function move_drive2drive (line 1289) | static int move_drive2drive(struct smc_priv *smc_p,
  function smc_move_medium (line 1382) | uint8_t smc_move_medium(struct scsi_cmd *cmd) {
  function smc_rezero (line 1472) | uint8_t smc_rezero(struct scsi_cmd *cmd) {
  function smc_open_close_import_export_element (line 1483) | uint8_t smc_open_close_import_export_element(struct scsi_cmd *cmd) {
  function smc_log_sense (line 1527) | uint8_t smc_log_sense(struct scsi_cmd *cmd) {
  function unload_drive_on_shutdown (line 1609) | void unload_drive_on_shutdown(struct s_info *src, struct s_info *dest) {

FILE: usr/spc.c
  type vpd (line 42) | struct vpd
  type vpd (line 43) | struct vpd
  type vpd (line 45) | struct vpd
  type vpd (line 48) | struct vpd
  function dealloc_vpd (line 62) | void dealloc_vpd(struct vpd *pg) {
  function spc_inquiry (line 67) | uint8_t spc_inquiry(struct scsi_cmd *cmd) {
  function resp_spc_pro (line 185) | uint8_t resp_spc_pro(uint8_t *cdb, struct mhvtl_ds *dbuf_p) {
  function resp_spc_pri (line 328) | uint8_t resp_spc_pri(uint8_t *cdb, struct mhvtl_ds *dbuf_p) {
  function spc_tur (line 386) | uint8_t spc_tur(struct scsi_cmd *cmd) {
  function spc_illegal_op (line 397) | uint8_t spc_illegal_op(struct scsi_cmd *cmd) {
  function spc_request_sense (line 411) | uint8_t spc_request_sense(struct scsi_cmd *cmd) {
  function spc_log_select (line 450) | uint8_t spc_log_select(struct scsi_cmd *cmd) {
  function spc_mode_select (line 502) | uint8_t spc_mode_select(struct scsi_cmd *cmd) {
  function add_pcode (line 513) | static int add_pcode(struct mode *m, uint8_t pc, uint8_t *p) {
  function spc_mode_sense (line 525) | uint8_t spc_mode_sense(struct scsi_cmd *cmd) {
  function spc_release (line 710) | uint8_t spc_release(struct scsi_cmd *cmd) {
  function spc_reserve (line 715) | uint8_t spc_reserve(struct scsi_cmd *cmd) {
  function spc_send_diagnostics (line 720) | uint8_t spc_send_diagnostics(struct scsi_cmd *cmd) {
  function spc_recv_diagnostics (line 725) | uint8_t spc_recv_diagnostics(struct scsi_cmd *cmd) {
  function spc_read_buffer (line 756) | uint8_t spc_read_buffer(struct scsi_cmd *cmd) {

FILE: usr/ssc.c
  type allow_overwrite_state (line 42) | struct allow_overwrite_state {
  function memset_ssc_buf (line 70) | void memset_ssc_buf(struct scsi_cmd *cmd, uint64_t alloc_len) {
  function ssc_allow_overwrite (line 76) | uint8_t ssc_allow_overwrite(struct scsi_cmd *cmd) {
  function ssc_log_select (line 134) | uint8_t ssc_log_select(struct scsi_cmd *cmd) {
  function complete_read_6 (line 155) | uint8_t complete_read_6(struct scsi_cmd *cmd, int sz, int count) {
  function ssc_verify_6 (line 302) | uint8_t ssc_verify_6(struct scsi_cmd *cmd) {
  function ssc_read_6 (line 340) | uint8_t ssc_read_6(struct scsi_cmd *cmd) {
  function ssc_write_6 (line 367) | uint8_t ssc_write_6(struct scsi_cmd *cmd) {
  function check_restrictions (line 414) | uint8_t check_restrictions(struct scsi_cmd *cmd) {
  function valid_encryption_blk (line 511) | uint8_t valid_encryption_blk(struct scsi_cmd *cmd) {
  function valid_encryption_media (line 545) | uint8_t valid_encryption_media(struct scsi_cmd *cmd) {
  function ssc_allow_prevent_removal (line 564) | uint8_t ssc_allow_prevent_removal(struct scsi_cmd *cmd) {
  function ssc_format_medium (line 572) | uint8_t ssc_format_medium(struct scsi_cmd *cmd) {
  function ssc_locate (line 609) | uint8_t ssc_locate(struct scsi_cmd *cmd) {
  function ssc_load_display (line 665) | uint8_t ssc_load_display(struct scsi_cmd *cmd) {
  function set_timestamp (line 732) | void set_timestamp(uint8_t source, uint64_t ts) {
  function get_timestamp (line 749) | static uint64_t get_timestamp() {
  function report_timestamp (line 765) | static uint8_t report_timestamp(struct scsi_cmd *cmd) {
  function configure_timestamp (line 780) | static uint8_t configure_timestamp(struct scsi_cmd *cmd) {
  function ssc_a3_service_action (line 815) | uint8_t ssc_a3_service_action(struct scsi_cmd *cmd) {
  function ssc_a4_service_action (line 839) | uint8_t ssc_a4_service_action(struct scsi_cmd *cmd) {
  function ssc_spout (line 863) | uint8_t ssc_spout(struct scsi_cmd *cmd) {
  function ssc_spin (line 878) | uint8_t ssc_spin(struct scsi_cmd *cmd) {
  function ssc_pr_out (line 885) | uint8_t ssc_pr_out(struct scsi_cmd *cmd) {
  function ssc_mode_select (line 903) | uint8_t ssc_mode_select(struct scsi_cmd *cmd) {
  function ssc_write_attributes (line 1192) | uint8_t ssc_write_attributes(struct scsi_cmd *cmd) {
  function ssc_tur (line 1221) | uint8_t ssc_tur(struct scsi_cmd *cmd) {
  function ssc_rewind (line 1290) | uint8_t ssc_rewind(struct scsi_cmd *cmd) {
  function ssc_read_attributes (line 1318) | uint8_t ssc_read_attributes(struct scsi_cmd *cmd) {
  function ssc_read_block_limits (line 1374) | uint8_t ssc_read_block_limits(struct scsi_cmd *cmd) {
  function ssc_read_media_sn (line 1397) | uint8_t ssc_read_media_sn(struct scsi_cmd *cmd) {
  function ssc_read_position (line 1472) | uint8_t ssc_read_position(struct scsi_cmd *cmd) {
  function ssc_release (line 1580) | uint8_t ssc_release(struct scsi_cmd *cmd) {
  function ssc_report_density_support (line 1592) | uint8_t ssc_report_density_support(struct scsi_cmd *cmd) {
  function ssc_reserve (line 1625) | uint8_t ssc_reserve(struct scsi_cmd *cmd) {
  function ssc_erase (line 1637) | uint8_t ssc_erase(struct scsi_cmd *cmd) {
  function ssc_space_6 (line 1662) | uint8_t ssc_space_6(struct scsi_cmd *cmd) {
  function ssc_space_16 (line 1714) | uint8_t ssc_space_16(struct scsi_cmd *cmd) {
  function ssc_load_unload (line 1753) | uint8_t ssc_load_unload(struct scsi_cmd *cmd) {
  function ssc_write_filemarks (line 1834) | uint8_t ssc_write_filemarks(struct scsi_cmd *cmd) {
  function ssc_pr_in (line 1868) | uint8_t ssc_pr_in(struct scsi_cmd *cmd) {
  function ssc_log_sense (line 1880) | uint8_t ssc_log_sense(struct scsi_cmd *cmd) {
  function ssc_recv_diagnostics (line 1963) | uint8_t ssc_recv_diagnostics(struct scsi_cmd *cmd) {
  function ssc_send_diagnostics (line 1979) | uint8_t ssc_send_diagnostics(struct scsi_cmd *cmd) {
  function ssc_set_capacity (line 2038) | uint8_t ssc_set_capacity(struct scsi_cmd *cmd) {

FILE: usr/utils/crc32c.c
  function gf2_matrix_times (line 60) | static inline uint32_t gf2_matrix_times(uint32_t *mat, uint32_t vec) {
  function gf2_matrix_square (line 73) | static inline void gf2_matrix_square(uint32_t *square, uint32_t *mat) {
  function crc32c_zeros_op (line 83) | static void crc32c_zeros_op(uint32_t *even, size_t len) {
  function crc32c_zeros (line 119) | static void crc32c_zeros(uint32_t zeros[][256], size_t len) {
  function crc32c_shift (line 132) | static inline uint32_t crc32c_shift(uint32_t zeros[][256], uint32_t crc) {
  function crc32c_init_hw (line 153) | static void crc32c_init_hw(void) {
  function crc32c_hw (line 160) | static uint32_t crc32c_hw(uint32_t crc, void const *buf, size_t len) {
  function crc32c (line 255) | uint32_t crc32c(uint32_t crc, void const *buf, size_t len) {
  function crc32c (line 262) | uint32_t crc32c(uint32_t crc, void const *buf, size_t len) {
  function crc32c_init_sw_little (line 271) | static void		crc32c_init_sw_little(void) {
  function crc32c_sw_little (line 296) | static uint32_t crc32c_sw_little(uint32_t crc, void const *buf, size_t l...
  function swap (line 335) | static inline uint64_t swap(uint64_t x) {
  function crc32c_init_sw_big (line 346) | static void		crc32c_init_sw_big(void) {
  function crc32c_sw_big (line 372) | static uint32_t crc32c_sw_big(uint32_t crc, void const *buf, size_t len) {
  function crc32c_sw (line 413) | static uint32_t crc32c_sw(uint32_t crc, void const *buf, size_t len) {

FILE: usr/utils/mhvtl_update.c
  type MAM_tapeFmtV3 (line 32) | struct MAM_tapeFmtV3 {
  function try_extract_mam (line 101) | int try_extract_mam(char *currentPCL) {
  function try_update_mam (line 230) | int try_update_mam(char *currentPCL) {
  function try_update_tape (line 386) | int try_update_tape(char *currentPCL) {

FILE: usr/utils/minilzo.c
  type lzo_int16e_hi_t__ (line 2764) | typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__)));
  type lzo_uint16e_hi_t__ (line 2765) | typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__)));
  type lzo_int32e_si_t__ (line 2799) | typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
  type lzo_uint32e_si_t__ (line 2800) | typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
  type lzo_int32e_si_t__ (line 2805) | typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
  type lzo_uint32e_si_t__ (line 2806) | typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
  type __w64 (line 2948) | typedef __w64 int                lzo_intptr_t;
  type lzo_uintptr_t (line 2949) | typedef __w64 unsigned int       lzo_uintptr_t;
  type lzo_word_t (line 3016) | typedef unsigned lzo_word_t  __attribute__((__mode__(__V16QI__)));
  type lzo_sword_t (line 3017) | typedef int      lzo_sword_t __attribute__((__mode__(__V16QI__)));
  function lzo_bitops_ctlz32_func (line 3434) | __lzo_static_forceinline unsigned lzo_bitops_ctlz32_func(lzo_uint32_t v)
  function lzo_bitops_ctlz64_func (line 3456) | __lzo_static_forceinline unsigned lzo_bitops_ctlz64_func(lzo_uint64_t v)
  function lzo_bitops_cttz32_func (line 3478) | __lzo_static_forceinline unsigned lzo_bitops_cttz32_func(lzo_uint32_t v)
  function lzo_bitops_cttz64_func (line 3497) | __lzo_static_forceinline unsigned lzo_bitops_cttz64_func(lzo_uint64_t v)
  type lzo_uint16_t (line 3543) | typedef lzo_uint16_t __lzo_may_alias
  type lzo_memops_TU2 (line 3547) | typedef struct lzo_memops_TU2_struct lzo_memops_TU2;
  type lzo_memops_TU2_struct (line 3549) | struct lzo_memops_TU2_struct { unsigned char a[2]; }
  type lzo_memops_TU2 (line 3550) | typedef struct lzo_memops_TU2_struct lzo_memops_TU2;
  type lzo_uint32_t (line 3558) | typedef lzo_uint32_t __lzo_may_alias
  type lzo_memops_TU4 (line 3562) | typedef struct lzo_memops_TU4_struct lzo_memops_TU4;
  type lzo_memops_TU4_struct (line 3564) | struct lzo_memops_TU4_struct { unsigned char a[4]; }
  type lzo_memops_TU4 (line 3565) | typedef struct lzo_memops_TU4_struct lzo_memops_TU4;
  type lzo_uint64_t (line 3573) | typedef lzo_uint64_t __lzo_may_alias
  type lzo_memops_TU8 (line 3577) | typedef struct lzo_memops_TU8_struct lzo_memops_TU8;
  type lzo_memops_TU8_struct (line 3579) | struct lzo_memops_TU8_struct { unsigned char a[8]; }
  type lzo_memops_TU8 (line 3580) | typedef struct lzo_memops_TU8_struct lzo_memops_TU8;
  function __lzo_static_forceinline (line 3699) | __lzo_static_forceinline lzo_uint16_t lzo_memops_get_le16(const lzo_void...
  function __lzo_static_forceinline (line 3721) | __lzo_static_forceinline lzo_uint32_t lzo_memops_get_le32(const lzo_void...
  function __lzo_static_forceinline (line 3747) | __lzo_static_forceinline lzo_uint16_t lzo_memops_get_ne16(const lzo_void...
  function __lzo_static_forceinline (line 3760) | __lzo_static_forceinline lzo_uint32_t lzo_memops_get_ne32(const lzo_void...
  function __lzo_static_forceinline (line 3778) | __lzo_static_forceinline void lzo_memops_put_le16(lzo_voidp dd, lzo_uint...
  function __lzo_static_forceinline (line 3798) | __lzo_static_forceinline void lzo_memops_put_le32(lzo_voidp dd, lzo_uint...
  function __lzo_static_forceinline (line 3820) | __lzo_static_forceinline void lzo_memops_put_ne16(lzo_voidp dd, lzo_uint...
  function __lzo_static_forceinline (line 3830) | __lzo_static_forceinline void lzo_memops_put_ne32(lzo_voidp dd, lzo_uint...
  type lzo_full_align_t (line 3977) | typedef union
  function __lzo_ptr_linear (line 4040) | LZO_PUBLIC(lzo_uintptr_t)
  function __lzo_align_gap (line 4056) | LZO_PUBLIC(unsigned)
  function lzo_copyright (line 4100) | LZO_PUBLIC(const lzo_bytep)
  function lzo_version (line 4106) | LZO_PUBLIC(unsigned)
  function lzo_version_string (line 4112) | LZO_PUBLIC(const char *)
  function lzo_version_date (line 4118) | LZO_PUBLIC(const char *)
  function _lzo_version_string (line 4124) | LZO_PUBLIC(const lzo_charp)
  function _lzo_version_date (line 4130) | LZO_PUBLIC(const lzo_charp)
  function lzo_adler32 (line 4145) | LZO_PUBLIC(lzo_uint32_t)
  function __lzo_noinline (line 4306) | static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off)
  function _lzo_config_check (line 4312) | LZO_PUBLIC(int)
  function __lzo_init_v2 (line 4414) | LZO_PUBLIC(int)
  function __pascal (line 4459) | __pascal LibMain ( int a, short b, short c, long d )
  function DVAL_ASSERT (line 4698) | static void __attribute__((__unused__))
  function __lzo_noinline (line 4790) | static __lzo_noinline lzo_uint
  function DO_COMPRESS (line 5077) | LZO_PUBLIC(int)

FILE: usr/utils/q.c
  function warn (line 29) | static void warn(char *s) {
  function init_queue (line 33) | int init_queue(void) {
  function send_msg (line 64) | int send_msg(char *cmd, long rcv_id) {
  function proc_obj (line 98) | static void proc_obj(struct q_entry *q_entry) {
  function enter (line 103) | int enter(char *objname, long rcv_id) {
  function serve (line 138) | int serve(void) {

FILE: usr/utils/reed-solomon.c
  function GenerateRSCRC (line 17) | uint32_t GenerateRSCRC(uint32_t crc, uint32_t cnt, const void *start) {
  function BlockProtectRSCRC (line 81) | uint32_t BlockProtectRSCRC(uint8_t *blkbuf, uint32_t blklen, int32_t big...
  function BlockVerifyRSCRC (line 108) | uint32_t BlockVerifyRSCRC(const uint8_t *blkbuf, uint32_t blklen, int32_...

FILE: usr/utils/subprocess.c
  function alarm_timeout (line 33) | void alarm_timeout(int sig) {
  function run_command (line 40) | int run_command(char *command, int timeout) {

FILE: usr/utils/validate_crc.c
  function main (line 18) | int main(int argc, char *argv[]) {

FILE: usr/vtl_cart_type.c
  function update_home_dir (line 67) | void update_home_dir(long lib_id) {
  function get_cart_type (line 74) | int get_cart_type(const char *barcode) {

FILE: usr/vtlcart.c
  type raw_header (line 57) | struct raw_header {
  type meta_header (line 69) | struct meta_header {
  type raw_header (line 82) | struct raw_header
  type meta_header (line 83) | struct meta_header
  type blk_header (line 92) | struct blk_header
  function mkEODHeader (line 120) | static int mkEODHeader(uint32_t blk_number, uint64_t data_offset) {
  function read_header (line 144) | static int read_header(uint32_t blk_number, uint8_t *sam_stat) {
  function tape_loaded (line 177) | static int tape_loaded(uint8_t *sam_stat) {
  function rewrite_meta_file (line 185) | static int rewrite_meta_file(void) {
  function check_for_overwrite (line 233) | static int check_for_overwrite(uint8_t *sam_stat) {
  function check_filemarks_alloc (line 285) | static int check_filemarks_alloc(uint32_t count) {
  function add_filemark (line 307) | static int add_filemark(uint32_t blk_number) {
  function rewind_tape (line 328) | int rewind_tape(uint8_t *sam_stat) {
  function position_to_eod (line 366) | int position_to_eod(uint8_t *sam_stat) {
  function position_to_block (line 385) | int position_to_block(uint32_t blk_number, uint8_t *sam_stat) {
  function position_blocks_forw (line 416) | int position_blocks_forw(uint64_t count, uint8_t *sam_stat) {
  function position_blocks_back (line 477) | int position_blocks_back(uint64_t count, uint8_t *sam_stat) {
  function position_filemarks_forw (line 536) | int position_filemarks_forw(uint64_t count, uint8_t *sam_stat) {
  function position_filemarks_back (line 573) | int position_filemarks_back(uint64_t count, uint8_t *sam_stat) {
  function read_mam (line 609) | int read_mam(int mam_fd, int mhvtl_fd, struct MAM *mamp) {
  function write_mam (line 704) | int write_mam(int mam_fd, int mhvtl_fd) {
  function rewriteMAM (line 756) | int rewriteMAM(uint8_t *sam_stat) {
  function unlink_partition (line 774) | static void unlink_partition(int partition_number) {
  function open_partition (line 791) | static int open_partition(uint8_t partition_number) {
  function close_partition (line 820) | static void close_partition(uint8_t partition_number) {
  function change_partition (line 832) | int change_partition(uint8_t partition_number) {
  function erase_partition (line 843) | static void erase_partition(uint8_t *sam_stat) {
  function create_partition (line 859) | static int create_partition(int partition_number) {
  function create_tape (line 908) | int create_tape(const char *pcl, uint8_t *sam_stat) {
  function load_partition (line 972) | int load_partition(const char *pcl, uint8_t *sam_stat, uint8_t error_che...
  function load_tape (line 1158) | int load_tape(const char *pcl, uint8_t *sam_stat) {
  function zero_filemark_count (line 1268) | void zero_filemark_count(void) {
  function format_partition (line 1277) | int format_partition(uint8_t *sam_stat) {
  function format_tape (line 1289) | int format_tape(uint8_t *sam_stat) {
  function write_filemarks (line 1318) | int write_filemarks(uint32_t count, uint8_t *sam_stat) {
  function write_tape_block (line 1394) | int write_tape_block(const uint8_t *buffer, uint32_t blk_size,
  function unload_tape (line 1527) | void unload_tape(uint8_t *sam_stat) {
  function read_tape_block (line 1556) | uint32_t read_tape_block(uint8_t *buf, uint32_t buf_size, uint8_t *sam_s...
  function current_tape_offset (line 1598) | uint64_t current_tape_offset(void) {
  function current_tape_block (line 1605) | uint64_t current_tape_block(void) {
  function last_block (line 1611) | uint64_t last_block(uint8_t partition_number) {
  function block_from_filemark (line 1615) | uint64_t block_from_filemark(uint8_t partition_number, uint32_t filemark) {
  function count_filemarks (line 1620) | uint64_t count_filemarks(int64_t block) {
  function enc_key_to_string (line 1636) | static void enc_key_to_string(char *dst, uint8_t *key, int len) {
  function print_raw_header (line 1649) | void print_raw_header(void) {
  function print_filemark_count (line 1736) | void print_filemark_count(void) {
  function print_metadata (line 1740) | void print_metadata(void) {
  function cart_deinit (line 1750) | void cart_deinit(void) {

FILE: usr/vtlcart_v1.c
  type raw_header (line 45) | struct raw_header {
  type raw_header (line 53) | struct raw_header
  function read_header (line 68) | static int read_header(struct raw_header *h, uint8_t *sam_stat) {
  function loff_t (line 82) | static loff_t position_to_curr_header(uint8_t *sam_stat) {
  function skip_to_next_header (line 86) | static int skip_to_next_header(uint8_t *sam_stat) {
  function skip_to_prev_header (line 113) | static int skip_to_prev_header(uint8_t *sam_stat) {
  function mkNewHeader (line 158) | static int mkNewHeader(uint32_t type, int blk_size, int comp_size,
  function mkEODHeader (line 253) | static int
  function skip_prev_filemark (line 276) | static int
  function skip_next_filemark (line 296) | static int
  function tape_loaded (line 318) | static int
  function position_to_eod (line 333) | int position_to_eod(uint8_t *sam_stat) {
  function rawRewind (line 352) | static int
  function rewind_tape (line 382) | int rewind_tape(uint8_t *sam_stat) {
  function position_to_block (line 444) | int position_to_block(uint32_t blk_no, uint8_t *sam_stat) {
  function position_blocks (line 476) | int position_blocks(int32_t count, uint8_t *sam_stat) {
  function position_filemarks (line 512) | int position_filemarks(int32_t count, uint8_t *sam_stat) {
  function rewriteMAM (line 536) | int rewriteMAM(uint8_t *sam_stat) {
  function create_tape (line 557) | int create_tape(const char *pcl, const struct MAM *mamp, uint8_t *sam_st...
  function load_tape (line 618) | int load_tape(const char *pcl, uint8_t *sam_stat) {
  function write_filemarks (line 701) | int write_filemarks(uint32_t count, uint8_t *sam_stat) {
  function write_tape_block (line 717) | int write_tape_block(const uint8_t *buf, uint32_t blk_size,
  function unload_tape (line 761) | void unload_tape(uint8_t *sam_stat) {
  function read_tape_block (line 768) | uint32_t read_tape_block(uint8_t *buf, uint32_t buf_size, uint8_t *sam_s...
  function current_tape_offset (line 787) | uint64_t
  function print_raw_header (line 795) | void print_raw_header(void) {

FILE: usr/vtlcart_v1_mtr.c
  type raw_header (line 50) | struct raw_header {
  type raw_header (line 59) | struct raw_header
  type MAM (line 66) | struct MAM
  type blk_header (line 67) | struct blk_header
  function read_header (line 77) | static int read_header(struct raw_header *h, uint8_t *sam_stat) {
  function loff_t (line 93) | static loff_t position_to_curr_header(uint8_t *sam_stat) {
  function skip_to_next_header (line 98) | static int skip_to_next_header(uint8_t *sam_stat) {
  function skip_to_prev_header (line 126) | static int skip_to_prev_header(uint8_t *sam_stat) {
  function mkNewHeader (line 172) | static int mkNewHeader(uint32_t type, int blk_size, int comp_size,
  function mkEODHeader (line 266) | static int mkEODHeader(uint8_t *sam_stat) {
  function skip_prev_filemark (line 289) | static int skip_prev_filemark(uint8_t *sam_stat) {
  function skip_next_filemark (line 309) | static int skip_next_filemark(uint8_t *sam_stat) {
  function tape_loaded (line 331) | static int tape_loaded(uint8_t *sam_stat) {
  function position_to_eod (line 346) | int position_to_eod(uint8_t *sam_stat) {
  function rawRewind (line 364) | static int rawRewind(uint8_t *sam_stat) {
  function rewind_tape (line 393) | int rewind_tape(uint8_t *sam_stat) {
  function position_to_block (line 458) | int position_to_block(uint32_t blk_no, uint8_t *sam_stat) {
  function position_blocks (line 491) | int position_blocks(int32_t count, uint8_t *sam_stat) {
  function position_filemarks (line 527) | int position_filemarks(int32_t count, uint8_t *sam_stat) {
  function position_blocks_forw (line 547) | int position_blocks_forw(uint32_t count, uint8_t *sam_stat) {
  function position_blocks_back (line 552) | int position_blocks_back(uint32_t count, uint8_t *sam_stat) {
  function position_filemarks_forw (line 557) | int position_filemarks_forw(uint32_t count, uint8_t *sam_stat) {
  function position_filemarks_back (line 562) | int position_filemarks_back(uint32_t count, uint8_t *sam_stat) {
  function rewriteMAM (line 571) | int rewriteMAM(uint8_t *sam_stat) {
  function create_tape (line 593) | int create_tape(const char *pcl, const struct MAM *mamp, uint8_t *sam_st...
  function load_tape (line 656) | int load_tape(const char *pcl, uint8_t *sam_stat) {
  function write_filemarks (line 748) | int write_filemarks(uint32_t count, uint8_t *sam_stat) {
  function write_tape_block (line 764) | int write_tape_block(const uint8_t *buf, uint32_t blk_size,
  function unload_tape (line 808) | void unload_tape(uint8_t *sam_stat) {
  function read_tape_block (line 816) | uint32_t read_tape_block(uint8_t *buf, uint32_t buf_size, uint8_t *sam_s...
  function current_tape_offset (line 836) | uint64_t current_tape_offset(void) {
  function print_raw_header (line 843) | void print_raw_header(void) {
  function check_for_overwrite (line 927) | static int check_for_overwrite(uint8_t *sam_stat) {
  function zero_filemark_count (line 981) | void zero_filemark_count(void) {
  function format_tape (line 993) | int format_tape(uint8_t *sam_stat) {
  function print_filemark_count (line 1006) | void print_filemark_count(void) {
  function print_metadata (line 1010) | void print_metadata(void) {

FILE: usr/vtllib.c
  type MAM (line 63) | struct MAM
  type priv_lu_ssc (line 64) | struct priv_lu_ssc
  type lu_phy_attr (line 65) | struct lu_phy_attr
  type encryption (line 66) | struct encryption
  function init_mam (line 99) | void init_mam(struct MAM *mamp) {
  function get_config (line 166) | int get_config(char *buf, conf_file conf, long id) {
  type state_description (line 218) | struct state_description {
  function mhvtl_prt_cdb (line 328) | void mhvtl_prt_cdb(int lvl, struct scsi_cmd *cmd) {
  function return_sense (line 417) | static void return_sense(uint8_t key, uint32_t asc_ascq, struct s_sd *sd,
  function sam_unit_attention (line 460) | void sam_unit_attention(uint16_t ascq, uint8_t *sam_stat) {
  function sam_not_ready (line 465) | void sam_not_ready(uint16_t ascq, uint8_t *sam_stat) {
  function sam_illegal_request (line 470) | void sam_illegal_request(uint16_t ascq, struct s_sd *sd, uint8_t *sam_st...
  function sam_medium_error (line 475) | void sam_medium_error(uint16_t ascq, uint8_t *sam_stat) {
  function sam_blank_check (line 480) | void sam_blank_check(uint16_t ascq, uint8_t *sam_stat) {
  function sam_data_protect (line 485) | void sam_data_protect(uint16_t ascq, uint8_t *sam_stat) {
  function sam_hardware_error (line 490) | void sam_hardware_error(uint16_t ascq, uint8_t *sam_stat) {
  function sam_no_sense (line 495) | void sam_no_sense(uint8_t key, uint16_t ascq, uint8_t *sam_stat) {
  function check_reset (line 500) | int check_reset(uint8_t *sam_stat) {
  function check_inquiry_data_has_changed (line 510) | int check_inquiry_data_has_changed(uint8_t *sam_stat) {
  function reset_device (line 521) | void reset_device(void) {
  function set_inquiry_data_changed (line 526) | void set_inquiry_data_changed(void) {
  function resp_read_block_limits (line 531) | int resp_read_block_limits(struct mhvtl_ds *dbuf_p, int sz) {
  function resp_read_media_serial (line 545) | uint32_t resp_read_media_serial(uint8_t *sno, uint8_t *buf, uint8_t *sam...
  function setTapeAlert (line 554) | void setTapeAlert(struct TapeAlert_pg *ta, uint64_t flg) {
  function retrieve_CDB_data (line 568) | int retrieve_CDB_data(int cdev, struct mhvtl_ds *ds) {
  function completeSCSICommand (line 587) | void completeSCSICommand(int cdev, struct mhvtl_ds *ds) {
  function hex_dump (line 610) | void hex_dump(uint8_t *p, int count) {
  function mhvtl_access (line 869) | static int mhvtl_access(char *p, int len, char *entry) {
  function pid_t (line 908) | pid_t add_lu(unsigned minor, struct mhvtl_ctl *ctl) {
  function chrdev_get_major (line 967) | static int chrdev_get_major(void) {
  function chrdev_create (line 997) | int chrdev_create(unsigned minor) {
  function chrdev_open (line 1033) | int chrdev_open(const char *name, unsigned minor) {
  function open_fifo (line 1079) | int open_fifo(FILE **fifo_fd, char *fifoname) {
  function status_change (line 1105) | void status_change(FILE *fifo_fd, int current_status, int m_id, char **m...
  function oom_adjust (line 1141) | int oom_adjust(void) {
  function blank_fill (line 1183) | void blank_fill(uint8_t *dest, char *src, int len) {
  function truncate_spaces (line 1194) | void truncate_spaces(char *s, int maxlen) {
  function log_opcode (line 1230) | void log_opcode(char *opcode, struct scsi_cmd *cmd) {
  function check_for_running_daemons (line 1242) | int check_for_running_daemons(unsigned minor) {
  function free_lock (line 1276) | int free_lock(unsigned minor) {
  function checkstrlen (line 1286) | void checkstrlen(char *s, unsigned int len, int lineno) {
  function device_type_register (line 1296) | int device_type_register(struct lu_phy_attr *lu, struct device_type_temp...
  function set_compression_mode_pg (line 1301) | uint8_t set_compression_mode_pg(struct list_head *l, int lvl) {
  function clear_compression_mode_pg (line 1326) | uint8_t clear_compression_mode_pg(struct list_head *l) {
  function clear_WORM (line 1351) | uint8_t clear_WORM(struct list_head *l) {
  function set_WORM (line 1371) | uint8_t set_WORM(struct list_head *l) {
  function rmnl (line 1395) | void rmnl(char *s, unsigned char c, int len) {
  function update_vpd_86 (line 1407) | void update_vpd_86(struct lu_phy_attr *lu, void *p) {
  function update_vpd_b0 (line 1421) | void update_vpd_b0(struct lu_phy_attr *lu, void *p) {
  function update_vpd_b1 (line 1430) | void update_vpd_b1(struct lu_phy_attr *lu, void *p) {
  function update_vpd_b2 (line 1436) | void update_vpd_b2(struct lu_phy_attr *lu, void *p) {
  function update_vpd_lbp (line 1443) | void update_vpd_lbp(struct lu_phy_attr *lu, void *p) {
  function update_vpd_c0 (line 1449) | void update_vpd_c0(struct lu_phy_attr *lu, void *p) {
  function update_vpd_c1 (line 1455) | void update_vpd_c1(struct lu_phy_attr *lu, void *p) {
  function cleanup_density_support (line 1461) | void cleanup_density_support(struct list_head *l) {
  function add_density_support (line 1470) | int add_density_support(struct list_head *l, struct density_info *di, in...
  function process_fifoname (line 1483) | void process_fifoname(struct lu_phy_attr *lu, char *s, int flag) {
  function cleanup_msg (line 1501) | void cleanup_msg(void) {
  function mhvtl_shared_mem (line 1523) | static int mhvtl_shared_mem(int flag) {
  function mhvtl_fifo_count (line 1581) | static int mhvtl_fifo_count(int direction) {
  function dec_fifo_count (line 1616) | int dec_fifo_count(void) {
  function inc_fifo_count (line 1620) | int inc_fifo_count(void) {
  function get_fifo_count (line 1624) | int get_fifo_count(void) {
  function find_media_home_directory (line 1633) | void find_media_home_directory(char *config_directory, long lib_id) {
  function set_media_params (line 1703) | unsigned int set_media_params(struct MAM *mamp, char *density) {
  function ymd (line 2029) | void ymd(int *year, int *month, int *day, int *hh, int *min, int *sec) {
  function opcode_6_params (line 2058) | void opcode_6_params(struct scsi_cmd *cmd, int *num, int *sz) {
  function init_smc_log_pages (line 2074) | void init_smc_log_pages(struct lu_phy_attr *lu) {
  function init_smc_mode_pages (line 2079) | void init_smc_mode_pages(struct lu_phy_attr *lu) {
  function bubbleSort (line 2089) | void bubbleSort(int *array, int size) {
  function sort_library_slot_type (line 2109) | void sort_library_slot_type(struct lu_phy_attr *lu, struct smc_type_slot...
  function update_vpd_80 (line 2142) | void update_vpd_80(struct lu_phy_attr *lu, void *p) {
  function update_vpd_83 (line 2150) | void update_vpd_83(struct lu_phy_attr *lu, void *p) {
Condensed preview — 155 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,846K chars).
[
  {
    "path": ".clang-format",
    "chars": 523,
    "preview": "BasedOnStyle: LLVM\nIndentWidth: 4\nUseTab: Always\nTabWidth: 4\nColumnLimit: 0\n\n# --- Includes ---\nIncludeBlocks: Preserve\n"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 2323,
    "preview": "# For most projects, this workflow file will not need changing; you simply need\n# to commit it to your repository.\n#\n# Y"
  },
  {
    "path": ".gitignore",
    "chars": 334,
    "preview": "*.ko\n*.o\n*~\n/cscope.*\n/kernel/.*.ko.cmd\n/kernel/.*.o.cmd\n/kernel/.tmp_versions/\n/kernel/mhvtl.mod.c\n/kernel/Module.symve"
  },
  {
    "path": "COPYING",
    "chars": 18487,
    "preview": "\n Note that the GPL below is copyrighted by the Free Software\n Foundation, but the instance of code that it refers to\n ("
  },
  {
    "path": "ChangeLog",
    "chars": 43324,
    "preview": "* Tue Mar 10 17:30:00 AEST 2026 Mark Harvey <markh794@gmail.com>\n- A hugh patch set to add LTFS support. Many thanks to "
  },
  {
    "path": "INSTALL",
    "chars": 5030,
    "preview": "mh virtual tape & library system.\n\n\nInstructions assume reader is familiar with the kernel build process.\n\nThere are two"
  },
  {
    "path": "Makefile",
    "chars": 2672,
    "preview": "#\n# This makefile needs to be invoked as follows:\n#\n#make <options>\n#\n# Here, options include:\n#\n# \tall \tto build all ut"
  },
  {
    "path": "README",
    "chars": 621,
    "preview": "\nmhvtl: A Virtual Tape & Library system.\n\nThis package is composed of a kernel module (mhvtl) which is a pseudo HBA\n\nThe"
  },
  {
    "path": "ccan/ccan/crc32c/_info",
    "chars": 1041,
    "preview": "#include \"config.h\"\n#include <string.h>\n#include <stdio.h>\n\n/**\n * crc32c - routine for Castagnoli CRC (crc32c) of bytes"
  },
  {
    "path": "ccan/ccan/crc32c/benchmark/Makefile",
    "chars": 642,
    "preview": "CCANDIR=../../..\nCFLAGS=-Wall -Werror -O3 -I$(CCANDIR) -flto\n#CFLAGS=-Wall -Werror -g3 -I$(CCANDIR)\nLDFLAGS := -flto -O3"
  },
  {
    "path": "ccan/ccan/crc32c/benchmark/bench.c",
    "chars": 1227,
    "preview": "#include <ccan/tal/grab_file/grab_file.h>\n#include <ccan/tal/tal.h>\n#include <ccan/time/time.h>\n#include <ccan/crc32c/cr"
  },
  {
    "path": "ccan/ccan/crc32c/crc32c.c",
    "chars": 15225,
    "preview": "/* MIT (BSD) license - see LICENSE file for details */\n/* crc32c.c -- compute CRC-32C using the Intel crc32 instruction\n"
  },
  {
    "path": "ccan/ccan/crc32c/crc32c.h",
    "chars": 1479,
    "preview": "/* Licensed under MIT - see LICENSE file for details */\n#ifndef CCAN_CRC32C_H\n#define CCAN_CRC32C_H\n#include <stdint.h>\n"
  },
  {
    "path": "ccan/ccan/crc32c/test/api-crc32c.c",
    "chars": 2224,
    "preview": "/* Test vectors from https://tools.ietf.org/html/rfc3720#appendix-B.4 */\n#include <ccan/crc32c/crc32c.h>\n#include <ccan/"
  },
  {
    "path": "ccan/ccan/crc32c/test/run-crc32c.c",
    "chars": 2282,
    "preview": "/* Test vectors from https://tools.ietf.org/html/rfc3720#appendix-B.4 */\n\n/* Get access to sw version explicitly */\n#inc"
  },
  {
    "path": "config.mk",
    "chars": 1070,
    "preview": "TOPDIR ?= $(CURDIR)\n\nVER ?= $(shell awk '/Version/ {print $$2}'  $(TOPDIR)/mhvtl-utils.spec)\nREL ?= $(shell awk -F'[ %]'"
  },
  {
    "path": "doc/4_library_example/device.conf",
    "chars": 9774,
    "preview": "\nVERSION: 3\n\n# VPD page format:\n# <page #> <Length> <x> <x+1>... <x+n>\n# NAA format is an 8 hex byte value seperated by "
  },
  {
    "path": "doc/4_library_example/library_contents.10",
    "chars": 1579,
    "preview": "VERSION: 2\n\nDrive 1:\nDrive 2:\nDrive 3:\nDrive 4:\nDrive 5:\nDrive 6:\nDrive 7:\nDrive 8:\nDrive 9:\n\nPicker 1:\n\nMAP 1:\nMAP 2:\nM"
  },
  {
    "path": "doc/4_library_example/library_contents.20",
    "chars": 1579,
    "preview": "VERSION: 2\n\nDrive 1:\nDrive 2:\nDrive 3:\nDrive 4:\nDrive 5:\nDrive 6:\nDrive 7:\nDrive 8:\nDrive 9:\n\nPicker 1:\n\nMAP 1:\nMAP 2:\nM"
  },
  {
    "path": "doc/4_library_example/library_contents.30",
    "chars": 1579,
    "preview": "VERSION: 2\n\nDrive 1:\nDrive 2:\nDrive 3:\nDrive 4:\nDrive 5:\nDrive 6:\nDrive 7:\nDrive 8:\nDrive 9:\n\nPicker 1:\n\nMAP 1:\nMAP 2:\nM"
  },
  {
    "path": "doc/4_library_example/library_contents.40",
    "chars": 1579,
    "preview": "VERSION: 2\n\nDrive 1:\nDrive 2:\nDrive 3:\nDrive 4:\nDrive 5:\nDrive 6:\nDrive 7:\nDrive 8:\nDrive 9:\n\nPicker 1:\n\nMAP 1:\nMAP 2:\nM"
  },
  {
    "path": "doc/4_library_example/mhvtl.conf",
    "chars": 202,
    "preview": "\n# Home directory for config file(s)\nMHVTL_CONFIG_PATH=/etc/mhvtl\n\n# Default media capacity (5 G)\nCAPACITY=5000\n\n# Set d"
  },
  {
    "path": "doc/index.html",
    "chars": 26804,
    "preview": "<html>\n\n<h1 align=\"center\">Welcome to Mark Harvey's home page</h1>\n\n<hr width=\"80%\">\n\n<h2 align=\"center\">Current project"
  },
  {
    "path": "etc/.gitignore",
    "chars": 174,
    "preview": "mhvtl.conf\ndevice.conf\nlibrary_contents.10\nlibrary_contents.30\nvtllibrary@.service\nvtltape@.service\nmhvtl-load-modules.s"
  },
  {
    "path": "etc/Makefile",
    "chars": 2289,
    "preview": "#\n# etc/Makefile\n#\n\nCURDIR = \"../\"\ninclude ../config.mk\n\nMHVTL_CONF_FILE = mhvtl.conf\nDEVICE_CONF_FILE = device.conf\nLIB"
  },
  {
    "path": "etc/generate_device_conf.in",
    "chars": 10411,
    "preview": "#!/bin/bash\n#\n# generate_device_conf -- generate device.conf output to stdout\n#\n#\tThis script generates the device.conf "
  },
  {
    "path": "etc/generate_library_contents.in",
    "chars": 4453,
    "preview": "#!/bin/bash\n#\n# generate_library_contents -- generate library_contents.* files\n#\n#\tThis script generates the library_con"
  },
  {
    "path": "etc/library_contents.sample",
    "chars": 1020,
    "preview": "# Define how many tape drives you want in the vtl..\n\nDrive 1:\nDrive 2:\nDrive 3:\nDrive 4:\nDrive 5:\nDrive 6:\nDrive 7:\nDriv"
  },
  {
    "path": "etc/mhvtl-load-modules.service.in",
    "chars": 402,
    "preview": "[Unit]\nDescription=Load mhvtl modules\nDocumentation=man:man:vtltape(1) man:man:vtllibrary(1)\nBefore=mhvtl.target\nPartOf="
  },
  {
    "path": "etc/mhvtl.conf.in",
    "chars": 296,
    "preview": "#\n# mhvtl.conf\n#\n\n# Home directory for tape emulation files\nMHVTL_HOME_PATH=@HOME_PATH@\n\n# Default media capacity (500 M"
  },
  {
    "path": "etc/mhvtl.target",
    "chars": 212,
    "preview": "[Unit]\nDescription=mhvtl service allowing to start/stop all vtltape@.service and vtllibrary@.service instances at once\nD"
  },
  {
    "path": "etc/vtllibrary@.service.in",
    "chars": 525,
    "preview": "[Unit]\nDocumentation=man:vtllibrary(1) man:vtlcmd(1)\nDescription=Robot Library Daemon for Virtual Tape & Robot Library\nB"
  },
  {
    "path": "etc/vtltape@.service.in",
    "chars": 471,
    "preview": "[Unit]\nDocumentation=man:vtltape(1) man:vtlcmd(1)\nDescription=Tape Daemon for Virtual Tape & Robot Library\nBefore=mhvtl."
  },
  {
    "path": "include/common/logging.h",
    "chars": 3539,
    "preview": "/*\n * logging macros\n *\n * Copyright (C) 2005-2025 Mark Harvey markh794@gmail.com\n *\n * This program is free software; y"
  },
  {
    "path": "include/common/mhvtl_scsi.h",
    "chars": 10586,
    "preview": "/*\n * The userspace tape/library header file for the vtl virtual\n * tape kernel module.\n *\n * Copyright (C) 2005 - 2025 "
  },
  {
    "path": "include/common/vtl_common.h",
    "chars": 925,
    "preview": "/* Common stuff for kernel and usr programs */\n#ifndef VTL_COMMON_H\n#define VTL_COMMON_H\n\n#define SENSE_BUF_SIZE 96\n/* M"
  },
  {
    "path": "include/common/vtl_u.h",
    "chars": 145,
    "preview": "/*\n * vtl_u.h\n */\n#define NETLINK_VTL 22\n\nstruct mhvtl_event {\n\tu32\t\t\ttid;\n\taligned_u64 sid;\n\taligned_u64 serial_no;\n\tu3"
  },
  {
    "path": "include/common/vtltape_pem.h",
    "chars": 1584,
    "preview": "static char *certificate =\n\t\"-----BEGIN CERTIFICATE-----\\n\"\n\t\"MIID9zCCA2CgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBtDELMAkGA1UEBh"
  },
  {
    "path": "include/mhvtl_log.h",
    "chars": 16377,
    "preview": "/*\n * This handles any SCSI OP 'log sense / log select'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail do"
  },
  {
    "path": "include/mode.h",
    "chars": 2764,
    "preview": "/*\n * This handles any SCSI OP 'mode sense / mode select'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail "
  },
  {
    "path": "include/smc.h",
    "chars": 2225,
    "preview": "#ifndef SMC_H\n#define SMC_H\n\n#include <stdint.h>\n\nstruct scsi_cmd;\nstruct s_info;\n\n/* Element type codes */\n#define ANY\t"
  },
  {
    "path": "include/spc.h",
    "chars": 1000,
    "preview": "\n#ifndef SPC_H\n#define SPC_H\n\n#include <stdint.h>\n\nstruct scsi_cmd;\n\n/* Variables for simple, single initiator, SCSI Res"
  },
  {
    "path": "include/ssc.h",
    "chars": 16828,
    "preview": "#ifndef SSC_H\n#define SSC_H\n\n#include <signal.h>\n#include <stdint.h>\n#include <sys/types.h>\n#include \"mhvtl_list.h\"\n#inc"
  },
  {
    "path": "include/utils/be_byteshift.h",
    "chars": 2137,
    "preview": "#ifndef _LINUX_UNALIGNED_BE_BYTESHIFT_H\n#define _LINUX_UNALIGNED_BE_BYTESHIFT_H\n\n#include <stdint.h>\n\nstatic inline uint"
  },
  {
    "path": "include/utils/lzoconf.h",
    "chars": 14633,
    "preview": "/* lzoconf.h -- configuration of the LZO data compression library\n\n   This file is part of the LZO real-time data compre"
  },
  {
    "path": "include/utils/lzodefs.h",
    "chars": 122223,
    "preview": "/* lzodefs.h -- architecture, OS and compiler specific defines\n\n   This file is part of the LZO real-time data compressi"
  },
  {
    "path": "include/utils/mhvtl_list.h",
    "chars": 2987,
    "preview": "#ifndef __LIST_H__\n#define __LIST_H__\n\n#include <stddef.h>\n/* taken from linux kernel */\n\n#undef offsetof\n#ifdef __compi"
  },
  {
    "path": "include/utils/mhvtl_update.h",
    "chars": 1045,
    "preview": "/*\n * Structures and Functions to update the tape format and mam format to new versions\n *\n * Copyright (C) 2005-2025 Ma"
  },
  {
    "path": "include/utils/minilzo.h",
    "chars": 3077,
    "preview": "/* minilzo.h -- mini subset of the LZO real-time data compression library\n\n   This file is part of the LZO real-time dat"
  },
  {
    "path": "include/utils/q.h",
    "chars": 1836,
    "preview": "/*\n * q.h -- Message queue for vtltape/vtllibrary\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail dot com\n"
  },
  {
    "path": "include/utils/security_protocol.h",
    "chars": 748,
    "preview": "\n#ifndef _SECURITY_PROTOCOL_H_\n#define _SECURITY_PROTOCOL_H_\n/*\n * Security Protocol IN/OUT\n *\n * Based on spc4r14 / ssc"
  },
  {
    "path": "include/utils/subprocess.h",
    "chars": 46,
    "preview": "\nint run_command(char *command, int timeout);\n"
  },
  {
    "path": "include/vtlcart.h",
    "chars": 7969,
    "preview": "/*\n * Describes the header layout of each tape 'block'\n *\n * $Id: vtlcart.h,v 1.1.2.1 2006-08-06 07:58:44 markh Exp $\n *"
  },
  {
    "path": "include/vtllib.h",
    "chars": 19469,
    "preview": "/*\n * The shared library libvtlscsi.so function defs\n *\n * Copyright (C) 2005-2025 Mark Harvey markh794@gmail.com\n *\n * "
  },
  {
    "path": "kernel/.gitignore",
    "chars": 16,
    "preview": "TAGS\n*.cmd\n*.mod"
  },
  {
    "path": "kernel/Makefile",
    "chars": 1954,
    "preview": "#\n# $Id: Makefile,v 1.2.2.3 2006-08-30 06:35:14 markh Exp $\n#\n\n# CC=/usr/bin/gcc\n#\nEXTRA_CFLAGS += -I$(SRC)/../include\nE"
  },
  {
    "path": "kernel/backport.h",
    "chars": 2263,
    "preview": "/*\n * Include wrappers for older kernels as interfaces change\n */\n\n#include \"config.h\"\n\n#ifndef SG_SEGMENT_SZ\n#define SG"
  },
  {
    "path": "kernel/config.sh",
    "chars": 5265,
    "preview": "#!/usr/bin/env bash\n# vim: tabstop=4 shiftwidth=4 expandtab colorcolumn=80 foldmethod=marker :\n\n# uncomment the next lin"
  },
  {
    "path": "kernel/fetch.c",
    "chars": 4518,
    "preview": "\n/*\n * Copy data from SCSI command buffer to device buffer\n *  (SCSI command buffer -> user space)\n *\n * Returns number "
  },
  {
    "path": "kernel/fetch24.c",
    "chars": 4615,
    "preview": "\n/*\n * Copy data from SCSI command buffer to device buffer\n *  (SCSI command buffer -> user space)\n *\n * Returns number "
  },
  {
    "path": "kernel/fetch26.c",
    "chars": 3575,
    "preview": "\n/*\n * Routines based on linux/lib/scatterlist.c\n */\n\n/**\n * sg_copy_buffer - Copy data between a linear buffer and an S"
  },
  {
    "path": "kernel/fetch27.c",
    "chars": 4014,
    "preview": "\n/**\n * mhvtl_sg_copy_user - Copy data between user-space linear buffer and an SG list\n * @sgl:\tThe SG list\n * @nents:\tN"
  },
  {
    "path": "kernel/fetch50.c",
    "chars": 3852,
    "preview": "\n\n/**\n * mhvtl_sg_copy_user - Copy data between user-space linear buffer and an SG list\n * @sgl:\tThe SG list\n * @nents:\t"
  },
  {
    "path": "kernel/mhvtl.c",
    "chars": 49812,
    "preview": "/*\n *  linux/kernel/vtl.c\n * vvvvvvvvvvvvvvvvvvvvvvv Original vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv\n *  Copyright (C) 1992  Er"
  },
  {
    "path": "man/Makefile",
    "chars": 1538,
    "preview": "#\n# This makefile needs to be invoked as follows:\n#\n#make <options>\n#\n# Here, options include:\n#\n# \tall \tto build all ut"
  },
  {
    "path": "man/device.conf.5.in",
    "chars": 3018,
    "preview": ".TH device.conf \"5\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\ndevice.conf \\- Configuration file for\n.B"
  },
  {
    "path": "man/dump_tape.1.in",
    "chars": 1245,
    "preview": ".TH dump_tape \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\ndump_tape \\- Utility to dump tape contents"
  },
  {
    "path": "man/edit_tape.1.in",
    "chars": 1599,
    "preview": ".TH edit_tape \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nedit_tape \\- Utility to update meta data v"
  },
  {
    "path": "man/generate_device_conf.1.in",
    "chars": 1620,
    "preview": ".TH generate_device_conf \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\ngenerate_device_conf \\- Utility"
  },
  {
    "path": "man/generate_library_contents.1.in",
    "chars": 1505,
    "preview": ".TH generate_library_contents \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\ngenerate_library_contents "
  },
  {
    "path": "man/library_contents.5.in",
    "chars": 1461,
    "preview": ".TH library_contents \"5\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nlibrary_contents \\- Configuration f"
  },
  {
    "path": "man/make_vtl_media.1.in",
    "chars": 2064,
    "preview": ".TH make_vtl_media \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nmake_vtl_media \\- create the library "
  },
  {
    "path": "man/mhvtl.conf.5.in",
    "chars": 1528,
    "preview": ".TH mhvtl.conf \"5\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nmhvtl.conf \\- Configuration file for\n.B v"
  },
  {
    "path": "man/mhvtl_kernel_mod_build.1.in",
    "chars": 1130,
    "preview": ".TH mhvtl_kernel_mod_build \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nmhvtl_kernel_mod_build \\- Sim"
  },
  {
    "path": "man/mktape.1.in",
    "chars": 2831,
    "preview": ".TH mktape \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nmktape \\- Utility to create new/blank virtual"
  },
  {
    "path": "man/preload_tape.1.in",
    "chars": 1536,
    "preview": ".TH preload_tape \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\npreload_tape \\- Utility to write a file"
  },
  {
    "path": "man/tapeexerciser.1.in",
    "chars": 900,
    "preview": ".TH tapeexerciser \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\ntapeexerciser \\- Utility to exercise v"
  },
  {
    "path": "man/update_device.conf.1.in",
    "chars": 891,
    "preview": ".TH update_device.conf \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nupdate_device.conf \\- Utility to "
  },
  {
    "path": "man/vtlcmd.1.in",
    "chars": 3176,
    "preview": ".TH vtlcmd \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nvtlcmd \\- user space utility to send commands"
  },
  {
    "path": "man/vtllibrary.1.in",
    "chars": 2462,
    "preview": ".TH vtllibrary \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nvtllibrary \\- user space daemon to handle"
  },
  {
    "path": "man/vtltape.1.in",
    "chars": 1539,
    "preview": ".TH vtltape \"1\" \"@MONTH@ @YEAR@\" \"mhvtl @VERSION@\" \"User Commands\"\n.SH NAME\nvtltape \\- user space daemon to handle SCSI "
  },
  {
    "path": "mhvtl-utils.spec",
    "chars": 6994,
    "preview": "# Disable the building of the debug package(s).\n%define debug_package %{nil}\n\n# config.sh parses '_firmwarepath' to defi"
  },
  {
    "path": "scripts/70-persistent-generic.rules",
    "chars": 802,
    "preview": "\n# Media changer\nACTION==\"add|change\", KERNEL==\"sg[0-9]*\", SUBSYSTEM==\"scsi_generic\", PROGRAM==\"/lib/udev/scsi_id --page"
  },
  {
    "path": "scripts/70-persistent-tape.rules",
    "chars": 694,
    "preview": "ACTION==\"add|change\", KERNEL==\"st[0-9]*\", SUBSYSTEM==\"scsi_tape\", ENV{ID_SERIAL}==\"350223344ff000100\", NAME=\"st0\"\nACTION"
  },
  {
    "path": "scripts/Makefile",
    "chars": 443,
    "preview": "\nCURDIR = \"../\"\ninclude ../config.mk\n\nRCFILE = update_device.conf\n\n$(RCFILE): $(RCFILE).in\n\tsed -e s'/@CONF_PATH@/$(CONF"
  },
  {
    "path": "scripts/NetBackup/drive_stats.pl",
    "chars": 3818,
    "preview": "#!/usr/bin/perl -w\n#\n# To be called from NetBackup volmgr/bin/drive_unmount_notify\n# Parses output of \"scsi_command -log"
  },
  {
    "path": "scripts/NetBackup/vlt_endeject_notify.pl",
    "chars": 3728,
    "preview": "#!/usr/bin/perl\n# vlt_endeject_notify\n#\n# This script is called after the vault job completes the eject processing for\n#"
  },
  {
    "path": "scripts/build-persistent-tape-rules.sh",
    "chars": 1358,
    "preview": "#!/bin/bash\n\n# To 'view' what are valid fields we can use - Pick a tape drive you are interested in. using /dev/st0 here"
  },
  {
    "path": "scripts/centos_configure.sh",
    "chars": 1686,
    "preview": "#!/bin/sh\n\n###  Install script for auto install mhvtl on CentOS Linux 6.2 i386/x86_64\n###  Version: 1.0.0\n###  made by p"
  },
  {
    "path": "scripts/checkarch.sh",
    "chars": 268,
    "preview": "#!/bin/sh\narch=`gcc -dumpmachine`\n\ncase $arch in\n`echo $arch | grep x86_64`)\n\techo -m64\n\t;;\n`echo $arch | grep \"i[3-6]86"
  },
  {
    "path": "scripts/checkpatch.pl",
    "chars": 81150,
    "preview": "#!/usr/bin/perl -w\n# (c) 2001, Dave Jones. (the file handling bit)\n# (c) 2005, Joel Schopp <jschopp@austin.ibm.com> (the"
  },
  {
    "path": "scripts/lio_target_passthru.sh",
    "chars": 1570,
    "preview": "#!/bin/bash\n\nif [ $# -ne 1 ]; then\n\techo \"Usage: $0 initiator_iqn (to add to iSCSI ACL)\"\n\texit\nfi\n# Use $1 if defined, o"
  },
  {
    "path": "scripts/mhvtl-1.4.ebuild",
    "chars": 1733,
    "preview": "# Copyright 1999-2010 Gentoo Foundation\n# Distributed under the terms of the GNU General Public License v2\n# $Header:\n\nE"
  },
  {
    "path": "scripts/rescan-scsi-bus.sh",
    "chars": 20445,
    "preview": "#!/bin/bash\n# Skript to rescan SCSI bus, using the\n# scsi add-single-device mechanism\n# (c) 1998--2008 Kurt Garloff <kur"
  },
  {
    "path": "scripts/start-mhvtl-scst.sh",
    "chars": 1221,
    "preview": "#!/bin/sh\n\nmodprobe mpt2sas\nmodprobe pl2303\n\nmodprobe scst\nmodprobe scst-vdisk\nmodprobe scst_tape\nmodprobe scst_changer\n"
  },
  {
    "path": "scripts/stgt-target-setup.conf",
    "chars": 443,
    "preview": "# This is a sample config file for tgt-admin.\n# By default, tgt-admin looks for its config file in /etc/tgt/targets.conf"
  },
  {
    "path": "scripts/test_lbp.sh",
    "chars": 3140,
    "preview": "#!/bin/bash\n\n#systemctl stop mhvtl\n#systemctl start mhvtl\n\nif [[ $EUID -ne 0 ]]; then\n   echo \"Sorry, this script needs "
  },
  {
    "path": "scripts/update_device.conf.in",
    "chars": 2492,
    "preview": "#!/usr/bin/perl -w\n#\n# Copyright (C) 2005 - 2025 Mark Harvey       markh794@gmail.com\n#\n# This program is free software;"
  },
  {
    "path": "tcopy/Makefile",
    "chars": 398,
    "preview": "# Makefile for linux port of Tcopy\n# By Nicholas Harbour, 2000\n\nCURDIR = \"../\"\ninclude ../config.mk\n\nBINARY=tcopy\nMANPAG"
  },
  {
    "path": "tcopy/pathnames.h",
    "chars": 1921,
    "preview": "/*\n * Copyright (c) 1989, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistributio"
  },
  {
    "path": "tcopy/tcopy.1",
    "chars": 3802,
    "preview": ".\\\" Copyright (c) 1985, 1990, 1991, 1993\n.\\\"\tThe Regents of the University of California.  All rights reserved.\n.\\\"\n.\\\" "
  },
  {
    "path": "tcopy/tcopy.c",
    "chars": 7848,
    "preview": "/*\n * Copyright (c) 1985, 1987, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistr"
  },
  {
    "path": "todo",
    "chars": 207,
    "preview": " - Review return values from functions and make consistent.\n   Some functions return SAM_STAT_XXX, some return *sam_stat"
  },
  {
    "path": "usr/.gitignore",
    "chars": 173,
    "preview": "mhvtl-device-conf-generator\ndump_messageQ\ndump_tape\nedit_tape\npreload_tape\nlibvtlcart.so\nlibvtlscsi.so\nmake_vtl_media\nmk"
  },
  {
    "path": "usr/Makefile",
    "chars": 6483,
    "preview": "#\n# This makefile needs to be invoked as follows:\n#\n#make <options>\n#\n# Here, options include:\n#\n# \tall \tto build all ut"
  },
  {
    "path": "usr/cmd/dump_messageQ.c",
    "chars": 2622,
    "preview": "/*\n * dump_messageQ - A utility to empty & examine a message queue\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 "
  },
  {
    "path": "usr/cmd/edit_tape.c",
    "chars": 7616,
    "preview": "/*\n * edit_tape is portion of the mhVTL package.\n *\n * The vtl package consists of:\n *   a kernel module (vlt.ko) - Curr"
  },
  {
    "path": "usr/cmd/make_scsi_dev",
    "chars": 1813,
    "preview": "#!/usr/bin/perl -w\n#\n# * perl replacement for the VERITAS /usr/openv/volmgr/bin/make_scsi_dev\n# *\n# * Re-creates the /de"
  },
  {
    "path": "usr/cmd/make_vtl_media.in",
    "chars": 8001,
    "preview": "#!/bin/bash\n#\n# Designed to be called from mhvtl rc script\n#\n# * Copyright (C) 2005 - 2025 Mark Harvey markh794@gmail.co"
  },
  {
    "path": "usr/cmd/mhvtl-device-conf-generator.c",
    "chars": 8902,
    "preview": "/*\n * mhvtl-device-conf-generator -- systemd generator for mhvtl\n *\n * This program read device.conf and creates the app"
  },
  {
    "path": "usr/cmd/mhvtl_kernel_mod_build.in",
    "chars": 348,
    "preview": "#!/bin/bash\n\n# Used to automate the building of the mhvtl.ko module\n# on a running system - without requiring the whole "
  },
  {
    "path": "usr/cmd/mktape.c",
    "chars": 6182,
    "preview": "/*\n * mktape\n *\n */\n\n#include <unistd.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#i"
  },
  {
    "path": "usr/cmd/tape_util.c",
    "chars": 16268,
    "preview": "/*\n *\tDump headers of 'tape' datafile\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail dot com\n *\n * This p"
  },
  {
    "path": "usr/cmd/tapeexerciser.c",
    "chars": 9904,
    "preview": "/*\n * Put a tape device thru a set of exercises\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include"
  },
  {
    "path": "usr/cmd/vtlcmd.c",
    "chars": 15475,
    "preview": "/*\n * vtlcmd - A utility to send a message queue to the vtltape/vtllibrary\n *\t    userspace daemons\n *\n * Copyright (C) "
  },
  {
    "path": "usr/cmd/vtllibrary.c",
    "chars": 49930,
    "preview": "/*\n * This daemon is the SCSI SMC target (Medium Changer) portion of the\n * vtl package.\n *\n * The vtl package consists "
  },
  {
    "path": "usr/cmd/vtltape.c",
    "chars": 71019,
    "preview": "/*\n * This daemon is the SCSI SSC target (Sequential device - tape drive)\n * portion of the vtl package.\n *\n * The vtl p"
  },
  {
    "path": "usr/mhvtl_io.c",
    "chars": 25456,
    "preview": "/*\n * mhvtl_io.c\n *\n * deduplicate code - Move Read/Write routines\n *\n * dump_tape / vtltape both use same functions\n * "
  },
  {
    "path": "usr/mhvtl_log.c",
    "chars": 29777,
    "preview": "/*\n * This handles any SCSI OP 'mode sense / mode select'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail "
  },
  {
    "path": "usr/mode.c",
    "chars": 34946,
    "preview": "/*\n * This handles any SCSI OP 'mode sense / mode select'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail "
  },
  {
    "path": "usr/pm/ait_pm.c",
    "chars": 15264,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/default_smc_pm.c",
    "chars": 1642,
    "preview": "/*\n * Personality module for default emulation\n */\n\n#include <stdio.h>\n#include <string.h>\n#include \"vtllib.h\"\n#include "
  },
  {
    "path": "usr/pm/default_ssc_pm.c",
    "chars": 16210,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/hp_smc_pm.c",
    "chars": 3230,
    "preview": "/*\n * Personality module for HP E-Series\n */\n\n#include <stdio.h>\n#include <string.h>\n#include \"vtllib.h\"\n#include \"smc.h"
  },
  {
    "path": "usr/pm/hp_ultrium_pm.c",
    "chars": 32145,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/ibm_03592_pm.c",
    "chars": 17782,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/ibm_smc_pm.c",
    "chars": 14602,
    "preview": "/*\n * Personality module for IBM TotalStorage(c) 3584 series of robots\n * e.g. TS3500\n */\n\n#include <stdio.h>\n#include <"
  },
  {
    "path": "usr/pm/overland_pm.c",
    "chars": 2489,
    "preview": "/*\n * Personality module for OVERLAND\n */\n\n#include <stdio.h>\n#include <string.h>\n#include \"vtllib.h\"\n#include \"smc.h\"\n#"
  },
  {
    "path": "usr/pm/quantum_dlt_pm.c",
    "chars": 17203,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/scalar_pm.c",
    "chars": 2891,
    "preview": "/*\n * Personality module for Scalar series of robots\n */\n\n#include <stdio.h>\n#include \"vtllib.h\"\n#include \"smc.h\"\n#inclu"
  },
  {
    "path": "usr/pm/spectra_pm.c",
    "chars": 4396,
    "preview": "/*\n * Personality module for Spectra Logic\n */\n\n#include \"vtllib.h\"\n#include \"smc.h\"\n#include \"logging.h\"\n#include \"mhvt"
  },
  {
    "path": "usr/pm/stk9x40_pm.c",
    "chars": 18041,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/stklxx_pm.c",
    "chars": 3277,
    "preview": "/*\n * Personality module for STK L series of robots\n * e.g. L180, L700, L20/40/80\n */\n\n#include <stdio.h>\n#include \"vtll"
  },
  {
    "path": "usr/pm/t10000_pm.c",
    "chars": 16684,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/pm/ult3580_pm.c",
    "chars": 36774,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/smc.c",
    "chars": 45247,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'MEDIUM CHANGER'\n *\n * Copyright (C) 2005 - 2025 Mark H"
  },
  {
    "path": "usr/spc.c",
    "chars": 19080,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'PRIMARY'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey m"
  },
  {
    "path": "usr/ssc.c",
    "chars": 64227,
    "preview": "/*\n * This handles any SCSI OP codes defined in the standards as 'STREAM'\n *\n * Copyright (C) 2005 - 2025 Mark Harvey ma"
  },
  {
    "path": "usr/utils/README.LZO",
    "chars": 4003,
    "preview": "\n ============================================================================\n miniLZO -- mini subset of the LZO real-t"
  },
  {
    "path": "usr/utils/crc32c.c",
    "chars": 13920,
    "preview": "/* MIT (BSD) license - see LICENSE file for details */\n/* crc32c.c -- compute CRC-32C using the Intel crc32 instruction\n"
  },
  {
    "path": "usr/utils/mhvtl_update.c",
    "chars": 13349,
    "preview": "/*\n * Functions to update the tape format and mam format to new versions\n *\n * Copyright (C) 2005 - 2025 Mark Harvey mar"
  },
  {
    "path": "usr/utils/minilzo.c",
    "chars": 208608,
    "preview": "/* minilzo.c -- mini subset of the LZO real-time data compression library\n\n   This file is part of the LZO real-time dat"
  },
  {
    "path": "usr/utils/q.c",
    "chars": 3712,
    "preview": "/*\n * From Unix System Programming -\n * Starting from Pg 195\n *\n * Advanced inter-process communications\n */\n\n#include <"
  },
  {
    "path": "usr/utils/reed-solomon.c",
    "chars": 6462,
    "preview": "/*\n * Reed-Solomon CRC defined in ECMA-319\n *\n * Lifted (copied) from IBM LTO reference guide Appendix D.\n */\n\n#include "
  },
  {
    "path": "usr/utils/subprocess.c",
    "chars": 1715,
    "preview": "/*\n * Run subprocess\n *\n * Copyright (C) 2012 Ivo De Decker ivo.dedecker@ugent.be\n *\n * This program is free software; y"
  },
  {
    "path": "usr/utils/validate_crc.c",
    "chars": 1474,
    "preview": "\n/*\n * Validate Reed-Solomon CRC and CRC32C routines pass\n * basic sanity check at compile time\n *\n * Shamelessly lifted"
  },
  {
    "path": "usr/vtl_cart_type.c",
    "chars": 3772,
    "preview": "/*\n * Version 2 of tape format.\n *\n * Each media contains 3 files.\n *  - The .data file contains each block of data writ"
  },
  {
    "path": "usr/vtlcart.c",
    "chars": 49162,
    "preview": "/*\n * Version 2 of tape format.\n *\n * Each media contains 3 files.\n *  - The .data file contains each block of data writ"
  },
  {
    "path": "usr/vtlcart_v1.c",
    "chars": 21137,
    "preview": "/*\n * Original tape format.\n *\n * Basically a double-linked-list headers followed by the block of data.\n * Each header d"
  },
  {
    "path": "usr/vtlcart_v1_mtr.c",
    "chars": 25016,
    "preview": "/*\n * Original tape format.\n *\n * Basically a double-linked-list headers followed by the block of data.\n * Each header d"
  },
  {
    "path": "usr/vtllib.c",
    "chars": 67860,
    "preview": "/*\n * Shared routines between vtltape & vtllibrary\n *\n * Copyright (C) 2005 - 2025 Mark Harvey markh794 at gmail dot com"
  },
  {
    "path": "vagrant/README.MD",
    "chars": 1951,
    "preview": "# Testing with Vagrant\nTo test mhvtl on different distros, we use vagrant to spin up virtual boxes with different distro"
  },
  {
    "path": "vagrant/Vagrantfile",
    "chars": 1450,
    "preview": "# -*- mode: ruby -*-\n# vi: set ft=ruby :\n\ndef gui_enabled?\n  !ENV.fetch('GUI', '').empty?\nend\n\nVagrant.configure(\"2\") do"
  },
  {
    "path": "vagrant/install.sh",
    "chars": 6426,
    "preview": "#!/bin/bash\n\n# This script assumes it is located in a subdirectory from 'mhvtl' source root\n\necho \"Script Begin\"\n\nget_os"
  },
  {
    "path": "webgui/index.php",
    "chars": 181,
    "preview": "<html>\n<head>\n</head>\n<body>\n\n<?php\n\necho \"<h1 align=\\\"center\\\">mhvtl configuration</h1>\";\n\necho \"<hr width=\\\"80%\\\">\";\n\n"
  }
]

About this extraction

This page contains the full source code of the markh794/mhvtl GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 155 files (1.6 MB), approximately 556.1k tokens, and a symbol index with 1450 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!