code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

========================================================
Adaptec Aic7xxx Fast -> Ultra160 Family Manager Set v7.0
========================================================

README for The Linux Operating System

The following information is available in this file:

  1. Supported Hardware
  2. Version History
  3. Command Line Options
  4. Contacting Adaptec

1. Supported Hardware
=====================

   The following Adaptec SCSI Chips and Host Adapters are supported by
   the aic7xxx driver.

   ======== ===== ========= ======== ========= ===== ===============
   Chip     MIPS  Host Bus  MaxSync  MaxWidth  SCBs  Notes
   ======== ===== ========= ======== ========= ===== ===============
   aic7770  10    EISA/VL   10MHz    16Bit      4    1
   aic7850  10    PCI/32    10MHz    8Bit       3
   aic7855  10    PCI/32    10MHz    8Bit       3
   aic7856  10    PCI/32    10MHz    8Bit       3
   aic7859  10    PCI/32    20MHz    8Bit       3
   aic7860  10    PCI/32    20MHz    8Bit       3
   aic7870  10    PCI/32    10MHz    16Bit      16
   aic7880  10    PCI/32    20MHz    16Bit      16
   aic7890  20    PCI/32    40MHz    16Bit      16      3 4 5 6 7 8
   aic7891  20    PCI/64    40MHz    16Bit      16      3 4 5 6 7 8
   aic7892  20    PCI/64-66 80MHz    16Bit      16      3 4 5 6 7 8
   aic7895  15    PCI/32    20MHz    16Bit      16    2 3 4 5
   aic7895C 15    PCI/32    20MHz    16Bit      16    2 3 4 5     8
   aic7896  20    PCI/32    40MHz    16Bit      16    2 3 4 5 6 7 8
   aic7897  20    PCI/64    40MHz    16Bit      16    2 3 4 5 6 7 8
   aic7899  20    PCI/64-66 80MHz    16Bit      16    2 3 4 5 6 7 8
   ======== ===== ========= ======== ========= ===== ===============

   1.   Multiplexed Twin Channel Device - One controller servicing two
        busses.
   2.   Multi-function Twin Channel Device - Two controllers on one chip.
   3.   Command Channel Secondary DMA Engine - Allows scatter gather list
        and SCB prefetch.
   4.   64 Byte SCB Support - Allows disconnected, untagged request table
        for all possible target/lun combinations.
   5.   Block Move Instruction Support - Doubles the speed of certain
        sequencer operations.
   6.   'Bayonet' style Scatter Gather Engine - Improves S/G prefetch
        performance.
   7.   Queuing Registers - Allows queuing of new transactions without
        pausing the sequencer.
   8.   Multiple Target IDs - Allows the controller to respond to selection
        as a target on multiple SCSI IDs.

   ============== ======= =========== =============== =============== =========
   Controller      Chip   Host-Bus    Int-Connectors  Ext-Connectors  Notes
   ============== ======= =========== =============== =============== =========
   AHA-274X[A]    aic7770   EISA         SE-50M         SE-HD50F
   AHA-274X[A]W   aic7770   EISA         SE-HD68F       SE-HD68F
                                         SE-50M
   AHA-274X[A]T   aic7770   EISA       2 X SE-50M       SE-HD50F
   AHA-2842       aic7770    VL          SE-50M         SE-HD50F
   AHA-2940AU     aic7860   PCI/32       SE-50M         SE-HD50F
   AVA-2902I      aic7860   PCI/32       SE-50M
   AVA-2902E      aic7860   PCI/32       SE-50M
   AVA-2906       aic7856   PCI/32       SE-50M         SE-DB25F
   APC-7850       aic7850   PCI/32       SE-50M                       1
   AVA-2940       aic7860   PCI/32       SE-50M
   AHA-2920B      aic7860   PCI/32       SE-50M
   AHA-2930B      aic7860   PCI/32       SE-50M
   AHA-2920C      aic7856   PCI/32       SE-50M         SE-HD50F
   AHA-2930C      aic7860   PCI/32       SE-50M
   AHA-2930C      aic7860   PCI/32       SE-50M
   AHA-2910C      aic7860   PCI/32       SE-50M
   AHA-2915C      aic7860   PCI/32       SE-50M
   AHA-2940AU/CN  aic7860   PCI/32       SE-50M         SE-HD50F
   AHA-2944W      aic7870   PCI/32     HVD-HD68F        HVD-HD68F
                                       HVD-50M
   AHA-3940W      aic7870   PCI/32     2 X SE-HD68F     SE-HD68F        2
   AHA-2940UW     aic7880   PCI/32       SE-HD68F
                                         SE-50M         SE-HD68F
   AHA-2940U      aic7880   PCI/32       SE-50M         SE-HD50F
   AHA-2940D      aic7880   PCI/32
   aHA-2940 A/T   aic7880   PCI/32
   AHA-2940D A/T  aic7880   PCI/32
   AHA-3940UW     aic7880   PCI/32     2 X SE-HD68F     SE-HD68F          3
   AHA-3940UWD    aic7880   PCI/32     2 X SE-HD68F   2 X SE-VHD68F       3
   AHA-3940U      aic7880   PCI/32     2 X SE-50M       SE-HD50F          3
   AHA-2944UW     aic7880   PCI/32      HVD-HD68F       HVD-HD68F
                                        HVD-50M
   AHA-3944UWD    aic7880   PCI/32     2 X HVD-HD68F  2 X HVD-VHD68F      3
   AHA-4944UW     aic7880   PCI/32
   AHA-2930UW     aic7880   PCI/32
   AHA-2940UW Pro aic7880   PCI/32      SE-HD68F        SE-HD68F            4
                                        SE-50M
   AHA-2940UW/CN  aic7880   PCI/32
   AHA-2940UDual  aic7895   PCI/32
   AHA-2940UWDual aic7895   PCI/32
   AHA-3940UWD    aic7895   PCI/32
   AHA-3940AUW    aic7895   PCI/32
   AHA-3940AUWD   aic7895   PCI/32
   AHA-3940AU     aic7895   PCI/32
   AHA-3944AUWD   aic7895   PCI/32     2 X HVD-HD68F  2 X HVD-VHD68F
   AHA-2940U2B    aic7890   PCI/32      LVD-HD68F       LVD-HD68F
   AHA-2940U2 OEM aic7891   PCI/64
   AHA-2940U2W    aic7890   PCI/32      LVD-HD68F       LVD-HD68F
                                        SE-HD68F
                                        SE-50M
   AHA-2950U2B    aic7891   PCI/64      LVD-HD68F       LVD-HD68F
   AHA-2930U2     aic7890   PCI/32      LVD-HD68F       SE-HD50F
                                        SE-50M
   AHA-3950U2B    aic7897   PCI/64
   AHA-3950U2D    aic7897   PCI/64
   AHA-29160      aic7892   PCI/64-66
   AHA-29160 CPQ  aic7892   PCI/64-66
   AHA-29160N     aic7892   PCI/32      LVD-HD68F       SE-HD50F
                                        SE-50M
   AHA-29160LP    aic7892   PCI/64-66
   AHA-19160      aic7892   PCI/64-66
   AHA-29150LP    aic7892   PCI/64-66
   AHA-29130LP    aic7892   PCI/64-66
   AHA-3960D      aic7899   PCI/64-66  2 X LVD-HD68F  2 X LVD-VHD68F
                                       LVD-50M
   AHA-3960D CPQ  aic7899   PCI/64-66  2 X LVD-HD68F  2 X LVD-VHD68F
                                       LVD-50M
   AHA-39160      aic7899   PCI/64-66  2 X LVD-HD68F  2 X LVD-VHD68F
                                       LVD-50M
   ============== ======= =========== =============== =============== =========

   1. No BIOS support
   2. DEC21050 PCI-PCI bridge with multiple controller chips on secondary bus
   3. DEC2115X PCI-PCI bridge with multiple controller chips on secondary bus
   4. All three SCSI connectors may be used simultaneously without
      SCSI "stub" effects.

2. Version History
==================

   * 7.0	  (4th August, 2005)
	- Updated driver to use SCSI transport class infrastructure
	- Upported sequencer and core fixes from last adaptec released
	  version of the driver.

   * 6.2.36 (June 3rd, 2003)
        - Correct code that disables PCI parity error checking.
        - Correct and simplify handling of the ignore wide residue
          message.  The previous code would fail to report a residual
          if the transaction data length was even and we received
          an IWR message.
        - Add support for the 2.5.X EISA framework.
        - Update for change in 2.5.X SCSI proc FS interface.
        - Correct Domain Validation command-line option parsing.
        - When negotiation async via an 8bit WDTR message, send
          an SDTR with an offset of 0 to be sure the target
          knows we are async.  This works around a firmware defect
          in the Quantum Atlas 10K.
        - Clear PCI error state during driver attach so that we
          don't disable memory mapped I/O due to a stray write
          by some other driver probe that occurred before we
          claimed the controller.

   * 6.2.35 (May 14th, 2003)
        - Fix a few GCC 3.3 compiler warnings.
        - Correct operation on EISA Twin Channel controller.
        - Add support for 2.5.X's scsi_report_device_reset().

   * 6.2.34 (May 5th, 2003)
        - Fix locking regression introduced in 6.2.29 that
          could cause a lock order reversal between the io_request_lock
          and our per-softc lock.  This was only possible on RH9,
          SuSE, and kernel.org 2.4.X kernels.

   * 6.2.33 (April 30th, 2003)
        - Dynamically disable PCI parity error reporting after
          10 errors are reported to the user.  These errors are
          the result of some other device issuing PCI transactions
          with bad parity.  Once the user has been informed of the
          problem, continuing to report the errors just degrades
          our performance.

   * 6.2.32 (March 28th, 2003)
        - Dynamically sized S/G lists to avoid SCSI malloc
          pool fragmentation and SCSI mid-layer deadlock.

   * 6.2.28 (January 20th, 2003)
        - Domain Validation Fixes
        - Add ability to disable PCI parity error checking.
        - Enhanced Memory Mapped I/O probe

   * 6.2.20 (November 7th, 2002)
        - Added Domain Validation.

3. Command Line Options
=======================

    .. Warning::

                 ALTERING OR ADDING THESE DRIVER PARAMETERS
                 INCORRECTLY CAN RENDER YOUR SYSTEM INOPERABLE.
                 USE THEM WITH CAUTION.

   Put a .conf file in the /etc/modprobe.d directory and add/edit a
   line containing ``options aic7xxx aic7xxx=[command[,command...]]`` where
   ``command`` is one or more of the following:

verbose

    :Definition: enable additional informative messages during driver operation.
    :Possible Values: This option is a flag
    :Default Value: disabled

debug:[value]

    :Definition: Enables various levels of debugging information
    :Possible Values: 0x0000 = no debugging, 0xffff = full debugging
    :Default Value: 0x0000

no_probe

probe_eisa_vl

    :Definition: Do not probe for EISA/VLB controllers.
		 This is a toggle.  If the driver is compiled
		 to not probe EISA/VLB controllers by default,
		 specifying "no_probe" will enable this probing.
		 If the driver is compiled to probe EISA/VLB
		 controllers by default, specifying "no_probe"
		 will disable this probing.

    :Possible Values: This option is a toggle
    :Default Value: EISA/VLB probing is disabled by default.

pci_parity

    :Definition: Toggles the detection of PCI parity errors.
		 On many motherboards with VIA chipsets,
		 PCI parity is not generated correctly on the
		 PCI bus.  It is impossible for the hardware to
		 differentiate between these "spurious" parity
		 errors and real parity errors.  The symptom of
		 this problem is a stream of the message::

		    "scsi0:	Data Parity Error Detected during address or write data phase"

		 output by the driver.

    :Possible Values: This option is a toggle
    :Default Value: PCI Parity Error reporting is disabled

no_reset

    :Definition: Do not reset the bus during the initial probe
		 phase

    :Possible Values: This option is a flag
    :Default Value: disabled

extended

    :Definition: Force extended translation on the controller
    :Possible Values: This option is a flag
    :Default Value: disabled

periodic_otag

    :Definition: Send an ordered tag periodically to prevent
		 tag starvation.  Needed for some older devices

    :Possible Values: This option is a flag
    :Default Value: disabled

reverse_scan

    :Definition: Probe the scsi bus in reverse order, starting
		with target 15

    :Possible Values: This option is a flag
    :Default Value: disabled

global_tag_depth:[value]

    :Definition: Global tag depth for all targets on all busses.
		 This option sets the default tag depth which
		 may be selectively overridden vi the tag_info
		 option.

    :Possible Values: 1 - 253
    :Default Value: 32

tag_info:{{value[,value...]}[,{value[,value...]}...]}

    :Definition: Set the per-target tagged queue depth on a
		 per controller basis.  Both controllers and targets
		 may be omitted indicating that they should retain
		 the default tag depth.

    :Possible Values: 1 - 253
    :Default Value: 32

    Examples:

	    ::

	        tag_info:{{16,32,32,64,8,8,,32,32,32,32,32,32,32,32,32}

	    On Controller 0:

		- specifies a tag depth of 16 for target 0
		- specifies a tag depth of 64 for target 3
		- specifies a tag depth of 8 for targets 4 and 5
		- leaves target 6 at the default
		- specifies a tag depth of 32 for targets 1,2,7-15
		- All other targets retain the default depth.

	    ::

                tag_info:{{},{32,,32}}

	    On Controller 1:

		- specifies a tag depth of 32 for targets 0 and 2
		- All other targets retain the default depth.

seltime:[value]

    :Definition: Specifies the selection timeout value
    :Possible Values: 0 = 256ms, 1 = 128ms, 2 = 64ms, 3 = 32ms
    :Default Value: 0

dv: {value[,value...]}

    :Definition: Set Domain Validation Policy on a per-controller basis.
		 Controllers may be omitted indicating that
		 they should retain the default read streaming setting.

    :Possible Values:

		      ==== ===============================
		       < 0 Use setting from serial EEPROM.
                         0 Disable DV
		       > 0 Enable DV
		      ==== ===============================

    :Default Value: SCSI-Select setting on controllers with a SCSI Select
		    option for DV.  Otherwise, on for controllers supporting
		    U160 speeds and off for all other controller types.

    Example:

	    ::

		dv:{-1,0,,1,1,0}

	   - On Controller 0 leave DV at its default setting.
	   - On Controller 1 disable DV.
	   - Skip configuration on Controller 2.
	   - On Controllers 3 and 4 enable DV.
	   - On Controller 5 disable DV.

Example::

    options aic7xxx aic7xxx=verbose,no_probe,tag_info:{{},{,,10}},seltime:1

enables verbose logging, Disable EISA/VLB probing,
and set tag depth on Controller 1/Target 2 to 10 tags.

4. Adaptec Customer Support
===========================

   A Technical Support Identification (TSID) Number is required for
   Adaptec technical support.

    - The 12-digit TSID can be found on the white barcode-type label
      included inside the box with your product.  The TSID helps us
      provide more efficient service by accurately identifying your
      product and support status.

   Support Options
    - Search the Adaptec Support Knowledgebase (ASK) at
      http://ask.adaptec.com for articles, troubleshooting tips, and
      frequently asked questions about your product.
    - For support via Email, submit your question to Adaptec's
      Technical Support Specialists at http://ask.adaptec.com/.

   North America
    - Visit our Web site at http://www.adaptec.com/.
    - For information about Adaptec's support options, call
      408-957-2550, 24 hours a day, 7 days a week.
    - To speak with a Technical Support Specialist,

      * For hardware products, call 408-934-7274,
        Monday to Friday, 3:00 am to 5:00 pm, PDT.
      * For RAID and Fibre Channel products, call 321-207-2000,
        Monday to Friday, 3:00 am to 5:00 pm, PDT.

      To expedite your service, have your computer with you.
    - To order Adaptec products, including accessories and cables,
      call 408-957-7274.  To order cables online go to
      http://www.adaptec.com/buy-cables/.

   Europe
    - Visit our Web site at http://www.adaptec.com/en-US/_common/world_index.
    - To speak with a Technical Support Specialist, call, or email,

      * German:  +49 89 4366 5522, Monday-Friday, 9:00-17:00 CET,
        http://ask-de.adaptec.com/.
      * French:  +49 89 4366 5533, Monday-Friday, 9:00-17:00 CET,
	http://ask-fr.adaptec.com/.
      * English: +49 89 4366 5544, Monday-Friday, 9:00-17:00 GMT,
	http://ask.adaptec.com/.

    - You can order Adaptec cables online at
      http://www.adaptec.com/buy-cables/.

   Japan
    - Visit our web site at http://www.adaptec.co.jp/.
    - To speak with a Technical Support Specialist, call
      +81 3 5308 6120, Monday-Friday, 9:00 a.m. to 12:00 p.m.,
      1:00 p.m. to 6:00 p.m.

Copyright |copy| 2003 Adaptec Inc. 691 S. Milpitas Blvd., Milpitas CA 95035 USA.

All rights reserved.

You are permitted to redistribute, use and modify this README file in whole
or in part in conjunction with redistribution of software governed by the
General Public License, provided that the following conditions are met:

1. Redistributions of README file must retain the above copyright
   notice, this list of conditions, and the following disclaimer,
   without modification.
2. The name of the author may not be used to endorse or promote products
   derived from this software without specific prior written permission.
3. Modifications or new contributions must be attributed in a copyright
   notice identifying the author ("Contributor") and added below the
   original copyright notice. The copyright notice is for purposes of
   identifying contributors and should not be deemed as permission to alter
   the permissions given by Adaptec.

THIS README FILE IS PROVIDED BY ADAPTEC AND CONTRIBUTORS ``AS IS`` AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, ANY
WARRANTIES OF NON-INFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
ADAPTEC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS README
FILE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


code:
ARECA FIRMWARE SPEC
===================

Usage of IOP331 adapter
=======================

(All In/Out is in IOP331's view)

1. Message 0
------------

- InitThread message and return code

2. Doorbell is used for RS-232 emulation
----------------------------------------

inDoorBell
    bit0
	data in ready
	zDRIVER DATA WRITE OK)
    bit1
	data out has been read
	(DRIVER DATA READ OK)

outDooeBell:
    bit0
	data out ready
	(IOP331 DATA WRITE OK)
    bit1
	data in has been read
	(IOP331 DATA READ OK)

3. Index Memory Usage
---------------------

============   ==========================================
offset 0xf00   for RS232 out (request buffer)
offset 0xe00   for RS232 in  (scratch buffer)
offset 0xa00   for inbound message code message_rwbuffer
	       (driver send to IOP331)
offset 0xa00   for outbound message code message_rwbuffer
	       (IOP331 send to driver)
============   ==========================================

4. RS-232 emulation
-------------------

Currently 128 byte buffer is used:

============   =====================
1st uint32_t   Data length (1--124)
Byte 4--127    Max 124 bytes of data
============   =====================

5. PostQ
--------

All SCSI Command must be sent through postQ:

    (inbound queue port)
	Request frame must be 32 bytes aligned:

	    #bit27--bit31
		flag for post ccb
	    #bit0--bit26
		real address (bit27--bit31) of post arcmsr_cdb

		=====   ===================
		bit31   ==  ===============
			0   256 bytes frame
			1   512 bytes frame
			==  ===============
		bit30   ==  ==============
			0   normal request
			1   BIOS request
			==  ==============
		bit29   reserved
		bit28   reserved
		bit27   reserved
		=====   ===================

    (outbount queue port)
	Request reply:

	    #bit27--bit31
		    flag for reply
	    #bit0--bit26
		    real address (bit27--bit31) of reply arcmsr_cdb

		    =====   =======================================================
		    bit31   must be 0 (for this type of reply)
		    bit30   reserved for BIOS handshake
		    bit29   reserved
		    bit28   ==  ===================================================
			    0   no error, ignore AdapStatus/DevStatus/SenseData
			    1   Error, error code in AdapStatus/DevStatus/SenseData
			    ==  ===================================================
		    bit27   reserved
		    =====   =======================================================

6. BIOS request
---------------

All BIOS request is the same with request from PostQ

Except:

Request frame is sent from configuration space:

	============   ==========================
	offset: 0x78   Request Frame (bit30 == 1)
	offset: 0x18   writeonly to generate
		       IRQ to IOP331
	============   ==========================

Completion of request::

	(bit30 == 0, bit28==err flag)

7. Definition of SGL entry (structure)
--------------------------------------

8. Message1 Out - Diag Status Code (????)
-----------------------------------------

9. Message0 message code
------------------------

======  =================================================================
0x00    NOP
0x01    Get Config
	->offset 0xa00 :for outbound message code message_rwbuffer
	(IOP331 send to driver)

	===================== ==========================================
	Signature             0x87974060(4)
	Request len           0x00000200(4)
	numbers of queue      0x00000100(4)
	SDRAM Size            0x00000100(4)-->256 MB
	IDE Channels          0x00000008(4)
	vendor                40 bytes char
	model                 8 bytes char
	FirmVer               16 bytes char
	Device Map            16 bytes char
	FirmwareVersion       DWORD

			      - Added for checking of
				new firmware capability
	===================== ==========================================
0x02    Set Config
	->offset 0xa00 :for inbound message code message_rwbuffer
	(driver send to IOP331)

	========================= ==================
	Signature                 0x87974063(4)
	UPPER32 of Request Frame  (4)-->Driver Only
	========================= ==================
0x03    Reset (Abort all queued Command)
0x04    Stop Background Activity
0x05    Flush Cache
0x06    Start Background Activity
	(re-start if background is halted)
0x07    Check If Host Command Pending
	(Novell May Need This Function)
0x08    Set controller time
	->offset 0xa00   for inbound message code message_rwbuffer
	(driver to IOP331)

	======   ==================
	byte 0   0xaa <-- signature
	byte 1   0x55 <-- signature
	byte 2   year (04)
	byte 3   month (1..12)
	byte 4   date (1..31)
	byte 5   hour (0..23)
	byte 6   minute (0..59)
	byte 7   second (0..59)
	======   ==================
======  =================================================================

RS-232 Interface for Areca Raid Controller
==========================================

      The low level command interface is exclusive with VT100 terminal

1. Sequence of command execution
--------------------------------

	(A) Header
		3 bytes sequence (0x5E, 0x01, 0x61)

	(B) Command block
		variable length of data including length,
		command code, data and checksum byte

	(C) Return data
		variable length of data

2. Command block
----------------

	(A) 1st byte
		command block length (low byte)

	(B) 2nd byte
		command block length (high byte)

		.. Note:: command block length shouldn't > 2040 bytes,
			  length excludes these two bytes

	(C) 3rd byte
		command code

	(D) 4th and following bytes
		variable length data bytes

	    depends on command code

	(E) last byte
	    checksum byte (sum of 1st byte until last data byte)

3. Command code and associated data
-----------------------------------

The following are command code defined in raid controller Command
code 0x10--0x1? are used for system level management,
no password checking is needed and should be implemented in separate
well controlled utility and not for end user access.
Command code 0x20--0x?? always check the password,
password must be entered to enable these command::

	enum
	{
		GUI_SET_SERIAL=0x10,
		GUI_SET_VENDOR,
		GUI_SET_MODEL,
		GUI_IDENTIFY,
		GUI_CHECK_PASSWORD,
		GUI_LOGOUT,
		GUI_HTTP,
		GUI_SET_ETHERNET_ADDR,
		GUI_SET_LOGO,
		GUI_POLL_EVENT,
		GUI_GET_EVENT,
		GUI_GET_HW_MONITOR,
		//    GUI_QUICK_CREATE=0x20, (function removed)
		GUI_GET_INFO_R=0x20,
		GUI_GET_INFO_V,
		GUI_GET_INFO_P,
		GUI_GET_INFO_S,
		GUI_CLEAR_EVENT,
		GUI_MUTE_BEEPER=0x30,
		GUI_BEEPER_SETTING,
		GUI_SET_PASSWORD,
		GUI_HOST_INTERFACE_MODE,
		GUI_REBUILD_PRIORITY,
		GUI_MAX_ATA_MODE,
		GUI_RESET_CONTROLLER,
		GUI_COM_PORT_SETTING,
		GUI_NO_OPERATION,
		GUI_DHCP_IP,
		GUI_CREATE_PASS_THROUGH=0x40,
		GUI_MODIFY_PASS_THROUGH,
		GUI_DELETE_PASS_THROUGH,
		GUI_IDENTIFY_DEVICE,
		GUI_CREATE_RAIDSET=0x50,
		GUI_DELETE_RAIDSET,
		GUI_EXPAND_RAIDSET,
		GUI_ACTIVATE_RAIDSET,
		GUI_CREATE_HOT_SPARE,
		GUI_DELETE_HOT_SPARE,
		GUI_CREATE_VOLUME=0x60,
		GUI_MODIFY_VOLUME,
		GUI_DELETE_VOLUME,
		GUI_START_CHECK_VOLUME,
		GUI_STOP_CHECK_VOLUME
	};

Command description
^^^^^^^^^^^^^^^^^^^

GUI_SET_SERIAL
	Set the controller serial#

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x10
	byte 3            password length (should be 0x0f)
	byte 4-0x13       should be "ArEcATecHnoLogY"
	byte 0x14--0x23   Serial number string (must be 16 bytes)
	================  =============================================

GUI_SET_VENDOR
	Set vendor string for the controller

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x11
	byte 3            password length (should be 0x08)
	byte 4-0x13       should be "ArEcAvAr"
	byte 0x14--0x3B   vendor string (must be 40 bytes)
	================  =============================================

GUI_SET_MODEL
	Set the model name of the controller

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x12
	byte 3            password length (should be 0x08)
	byte 4-0x13       should be "ArEcAvAr"
	byte 0x14--0x1B   model string (must be 8 bytes)
	================  =============================================

GUI_IDENTIFY
	Identify device

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x13
			    return "Areca RAID Subsystem "
	================  =============================================

GUI_CHECK_PASSWORD
	Verify password

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x14
	byte 3            password length
	byte 4-0x??       user password to be checked
	================  =============================================

GUI_LOGOUT
	Logout GUI (force password checking on next command)

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x15
	================  =============================================

GUI_HTTP
	HTTP interface (reserved for Http proxy service)(0x16)

GUI_SET_ETHERNET_ADDR
	Set the ethernet MAC address

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x17
	byte 3            password length (should be 0x08)
	byte 4-0x13       should be "ArEcAvAr"
	byte 0x14--0x19   Ethernet MAC address (must be 6 bytes)
	================  =============================================

GUI_SET_LOGO
	Set logo in HTTP

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x18
	byte 3            Page# (0/1/2/3) (0xff --> clear OEM logo)
	byte 4/5/6/7      0x55/0xaa/0xa5/0x5a
	byte 8            TITLE.JPG data (each page must be 2000 bytes)

			  .. Note:: page0 1st 2 byte must be
				    actual length of the JPG file
	================  =============================================

GUI_POLL_EVENT
	Poll If Event Log Changed

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x19
	================  =============================================

GUI_GET_EVENT
	Read Event

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x1a
	byte 3            Event Page (0:1st page/1/2/3:last page)
	================  =============================================

GUI_GET_HW_MONITOR
	Get HW monitor data

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x1b
	byte 3 		  # of FANs(example 2)
	byte 4 		  # of Voltage sensor(example 3)
	byte 5 		  # of temperature sensor(example 2)
	byte 6 		  # of power
	byte 7/8          Fan#0 (RPM)
	byte 9/10         Fan#1
	byte 11/12 	  Voltage#0 original value in ``*1000``
	byte 13/14 	  Voltage#0 value
	byte 15/16 	  Voltage#1 org
	byte 17/18 	  Voltage#1
	byte 19/20 	  Voltage#2 org
	byte 21/22 	  Voltage#2
	byte 23 	  Temp#0
	byte 24 	  Temp#1
	byte 25 	  Power indicator (bit0   power#0,
			  bit1   power#1)
	byte 26 	  UPS indicator
	================  =============================================

GUI_QUICK_CREATE
	Quick create raid/volume set

	================  ==============================================
	byte 0,1       	  length
	byte 2         	  command code 0x20
	byte 3/4/5/6   	  raw capacity
	byte 7 		  raid level
	byte 8 		  stripe size
	byte 9 		  spare
	byte 10/11/12/13  device mask (the devices to create raid/volume)
	================  ==============================================

    This function is removed, application like
    to implement quick create function

    need to use GUI_CREATE_RAIDSET and GUI_CREATE_VOLUMESET function.

GUI_GET_INFO_R
	Get Raid Set Information

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x20
	byte 3            raidset#
	================  =============================================

	::

	    typedef struct sGUI_RAIDSET
	    {
		    BYTE grsRaidSetName[16];
		    DWORD grsCapacity;
		    DWORD grsCapacityX;
		    DWORD grsFailMask;
		    BYTE grsDevArray[32];
		    BYTE grsMemberDevices;
		    BYTE grsNewMemberDevices;
		    BYTE grsRaidState;
		    BYTE grsVolumes;
		    BYTE grsVolumeList[16];
		    BYTE grsRes1;
		    BYTE grsRes2;
		    BYTE grsRes3;
		    BYTE grsFreeSegments;
		    DWORD grsRawStripes[8];
		    DWORD grsRes4;
		    DWORD grsRes5; //     Total to 128 bytes
		    DWORD grsRes6; //     Total to 128 bytes
	    } sGUI_RAIDSET, *pGUI_RAIDSET;

GUI_GET_INFO_V
	Get Volume Set Information

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x21
	byte 3            volumeset#
	================  =============================================

	::

	    typedef struct sGUI_VOLUMESET
	    {
		    BYTE gvsVolumeName[16]; //     16
		    DWORD gvsCapacity;
		    DWORD gvsCapacityX;
		    DWORD gvsFailMask;
		    DWORD gvsStripeSize;
		    DWORD gvsNewFailMask;
		    DWORD gvsNewStripeSize;
		    DWORD gvsVolumeStatus;
		    DWORD gvsProgress; //     32
		    sSCSI_ATTR gvsScsi;
		    BYTE gvsMemberDisks;
		    BYTE gvsRaidLevel; //     8
		    BYTE gvsNewMemberDisks;
		    BYTE gvsNewRaidLevel;
		    BYTE gvsRaidSetNumber;
		    BYTE gvsRes0; //     4
		    BYTE gvsRes1[4]; //     64 bytes
	    } sGUI_VOLUMESET, *pGUI_VOLUMESET;

GUI_GET_INFO_P
	Get Physical Drive Information

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x22
	byte 3            drive # (from 0 to max-channels - 1)
	================  =============================================

	::

	    typedef struct sGUI_PHY_DRV
	    {
		    BYTE gpdModelName[40];
		    BYTE gpdSerialNumber[20];
		    BYTE gpdFirmRev[8];
		    DWORD gpdCapacity;
		    DWORD gpdCapacityX; //     Reserved for expansion
		    BYTE gpdDeviceState;
		    BYTE gpdPioMode;
		    BYTE gpdCurrentUdmaMode;
		    BYTE gpdUdmaMode;
		    BYTE gpdDriveSelect;
		    BYTE gpdRaidNumber; //     0xff if not belongs to a raid set
		    sSCSI_ATTR gpdScsi;
		    BYTE gpdReserved[40]; //     Total to 128 bytes
	    } sGUI_PHY_DRV, *pGUI_PHY_DRV;

GUI_GET_INFO_S
	Get System Information

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x23
	================  =============================================

	::

	    typedef struct sCOM_ATTR
	    {
		    BYTE comBaudRate;
		    BYTE comDataBits;
		    BYTE comStopBits;
		    BYTE comParity;
		    BYTE comFlowControl;
	    } sCOM_ATTR, *pCOM_ATTR;
	    typedef struct sSYSTEM_INFO
	    {
		    BYTE gsiVendorName[40];
		    BYTE gsiSerialNumber[16];
		    BYTE gsiFirmVersion[16];
		    BYTE gsiBootVersion[16];
		    BYTE gsiMbVersion[16];
		    BYTE gsiModelName[8];
		    BYTE gsiLocalIp[4];
		    BYTE gsiCurrentIp[4];
		    DWORD gsiTimeTick;
		    DWORD gsiCpuSpeed;
		    DWORD gsiICache;
		    DWORD gsiDCache;
		    DWORD gsiScache;
		    DWORD gsiMemorySize;
		    DWORD gsiMemorySpeed;
		    DWORD gsiEvents;
		    BYTE gsiMacAddress[6];
		    BYTE gsiDhcp;
		    BYTE gsiBeeper;
		    BYTE gsiChannelUsage;
		    BYTE gsiMaxAtaMode;
		    BYTE gsiSdramEcc; //     1:if ECC enabled
		    BYTE gsiRebuildPriority;
		    sCOM_ATTR gsiComA; //     5 bytes
		    sCOM_ATTR gsiComB; //     5 bytes
		    BYTE gsiIdeChannels;
		    BYTE gsiScsiHostChannels;
		    BYTE gsiIdeHostChannels;
		    BYTE gsiMaxVolumeSet;
		    BYTE gsiMaxRaidSet;
		    BYTE gsiEtherPort; //     1:if ether net port supported
		    BYTE gsiRaid6Engine; //     1:Raid6 engine supported
		    BYTE gsiRes[75];
	    } sSYSTEM_INFO, *pSYSTEM_INFO;

GUI_CLEAR_EVENT
	Clear System Event

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x24
	================  =============================================

GUI_MUTE_BEEPER
	Mute current beeper

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x30
	================  =============================================
GUI_BEEPER_SETTING
	Disable beeper

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x31
	byte 3            0->disable, 1->enable
	================  =============================================

GUI_SET_PASSWORD
	Change password

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x32
	byte 3 		  pass word length ( must <= 15 )
	byte 4 		  password (must be alpha-numerical)
	================  =============================================

GUI_HOST_INTERFACE_MODE
	Set host interface mode

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x33
	byte 3 		  0->Independent, 1->cluster
	================  =============================================

GUI_REBUILD_PRIORITY
	Set rebuild priority

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x34
	byte 3 		  0/1/2/3 (low->high)
	================  =============================================

GUI_MAX_ATA_MODE
	Set maximum ATA mode to be used

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x35
	byte 3 		  0/1/2/3 (133/100/66/33)
	================  =============================================

GUI_RESET_CONTROLLER
	Reset Controller

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x36
			  * Response with VT100 screen (discard it)
	================  =============================================

GUI_COM_PORT_SETTING
	COM port setting

	================  =================================================
	byte 0,1	  length
	byte 2 		  command code 0x37
	byte 3 		  0->COMA (term port),
			  1->COMB (debug port)
	byte 4 		  0/1/2/3/4/5/6/7
			  (1200/2400/4800/9600/19200/38400/57600/115200)
	byte 5 		  data bit
			  (0:7 bit, 1:8 bit   must be 8 bit)
	byte 6 		  stop bit (0:1, 1:2 stop bits)
	byte 7 		  parity (0:none, 1:off, 2:even)
	byte 8 		  flow control
			  (0:none, 1:xon/xoff, 2:hardware => must use none)
	================  =================================================

GUI_NO_OPERATION
	No operation

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x38
	================  =============================================

GUI_DHCP_IP
	Set DHCP option and local IP address

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x39
	byte 3            0:dhcp disabled, 1:dhcp enabled
	byte 4/5/6/7      IP address
	================  =============================================

GUI_CREATE_PASS_THROUGH
	Create pass through disk

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x40
	byte 3 		  device #
	byte 4 		  scsi channel (0/1)
	byte 5 		  scsi id (0-->15)
	byte 6 		  scsi lun (0-->7)
	byte 7 		  tagged queue (1   enabled)
	byte 8 		  cache mode (1   enabled)
	byte 9 		  max speed (0/1/2/3/4,
			  async/20/40/80/160 for scsi)
			  (0/1/2/3/4, 33/66/100/133/150 for ide  )
	================  =============================================

GUI_MODIFY_PASS_THROUGH
	Modify pass through disk

	================  =============================================
	byte 0,1          length
	byte 2 		  command code 0x41
	byte 3 		  device #
	byte 4 		  scsi channel (0/1)
	byte 5 		  scsi id (0-->15)
	byte 6 		  scsi lun (0-->7)
	byte 7 		  tagged queue (1   enabled)
	byte 8 		  cache mode (1   enabled)
	byte 9 		  max speed (0/1/2/3/4,
			  async/20/40/80/160 for scsi)
			  (0/1/2/3/4, 33/66/100/133/150 for ide  )
	================  =============================================

GUI_DELETE_PASS_THROUGH
	Delete pass through disk

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x42
	byte 3            device# to be deleted
	================  =============================================
GUI_IDENTIFY_DEVICE
	Identify Device

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x43
	byte 3            Flash Method
			  (0:flash selected, 1:flash not selected)
	byte 4/5/6/7      IDE device mask to be flashed
			  .. Note:: no response data available
	================  =============================================

GUI_CREATE_RAIDSET
	Create Raid Set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x50
	byte 3/4/5/6      device mask
	byte 7-22         raidset name (if byte 7 == 0:use default)
	================  =============================================

GUI_DELETE_RAIDSET
	Delete Raid Set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x51
	byte 3            raidset#
	================  =============================================

GUI_EXPAND_RAIDSET
	Expand Raid Set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x52
	byte 3            raidset#
	byte 4/5/6/7      device mask for expansion
	byte 8/9/10       (8:0 no change, 1 change, 0xff:terminate,
			  9:new raid level,
			  10:new stripe size
			  0/1/2/3/4/5->4/8/16/32/64/128K )
	byte 11/12/13     repeat for each volume in the raidset
	================  =============================================

GUI_ACTIVATE_RAIDSET
	Activate incomplete raid set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x53
	byte 3            raidset#
	================  =============================================

GUI_CREATE_HOT_SPARE
	Create hot spare disk

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x54
	byte 3/4/5/6      device mask for hot spare creation
	================  =============================================

GUI_DELETE_HOT_SPARE
	Delete hot spare disk

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x55
	byte 3/4/5/6      device mask for hot spare deletion
	================  =============================================

GUI_CREATE_VOLUME
	Create volume set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x60
	byte 3            raidset#
	byte 4-19         volume set name
			  (if byte4 == 0, use default)
	byte 20-27        volume capacity (blocks)
	byte 28 	  raid level
	byte 29 	  stripe size
			  (0/1/2/3/4/5->4/8/16/32/64/128K)
	byte 30 	  channel
	byte 31 	  ID
	byte 32 	  LUN
	byte 33 	  1 enable tag
	byte 34 	  1 enable cache
	byte 35 	  speed
			  (0/1/2/3/4->async/20/40/80/160 for scsi)
			  (0/1/2/3/4->33/66/100/133/150 for IDE  )
	byte 36 	  1 to select quick init
	================  =============================================

GUI_MODIFY_VOLUME
	Modify volume Set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x61
	byte 3            volumeset#
	byte 4-19         new volume set name
			  (if byte4 == 0, not change)
	byte 20-27        new volume capacity (reserved)
	byte 28 	  new raid level
	byte 29 	  new stripe size
			  (0/1/2/3/4/5->4/8/16/32/64/128K)
	byte 30 	  new channel
	byte 31 	  new ID
	byte 32 	  new LUN
	byte 33 	  1 enable tag
	byte 34 	  1 enable cache
	byte 35 	  speed
			  (0/1/2/3/4->async/20/40/80/160 for scsi)
			  (0/1/2/3/4->33/66/100/133/150 for IDE  )
	================  =============================================

GUI_DELETE_VOLUME
	Delete volume set

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x62
	byte 3            volumeset#
	================  =============================================

GUI_START_CHECK_VOLUME
	Start volume consistency check

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x63
	byte 3            volumeset#
	================  =============================================

GUI_STOP_CHECK_VOLUME
	Stop volume consistency check

	================  =============================================
	byte 0,1          length
	byte 2            command code 0x64
	================  =============================================

4. Returned data
----------------

(A) Header
    3 bytes sequence (0x5E, 0x01, 0x61)
(B) Length
    2 bytes
    (low byte 1st, excludes length and checksum byte)
(C)
    status or data:

	1) If length == 1 ==> 1 byte status code::

		#define GUI_OK                    0x41
		#define GUI_RAIDSET_NOT_NORMAL    0x42
		#define GUI_VOLUMESET_NOT_NORMAL  0x43
		#define GUI_NO_RAIDSET            0x44
		#define GUI_NO_VOLUMESET          0x45
		#define GUI_NO_PHYSICAL_DRIVE     0x46
		#define GUI_PARAMETER_ERROR       0x47
		#define GUI_UNSUPPORTED_COMMAND   0x48
		#define GUI_DISK_CONFIG_CHANGED   0x49
		#define GUI_INVALID_PASSWORD      0x4a
		#define GUI_NO_DISK_SPACE         0x4b
		#define GUI_CHECKSUM_ERROR        0x4c
		#define GUI_PASSWORD_REQUIRED     0x4d

	2) If length > 1:

		data block returned from controller
		and the contents depends on the command code

(E) Checksum
    checksum of length and status or data byte

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

===========================
Operating FCoE using bnx2fc
===========================
Broadcom FCoE offload through bnx2fc is full stateful hardware offload that
cooperates with all interfaces provided by the Linux ecosystem for FC/FCoE and
SCSI controllers.  As such, FCoE functionality, once enabled is largely
transparent. Devices discovered on the SAN will be registered and unregistered
automatically with the upper storage layers.

Despite the fact that the Broadcom's FCoE offload is fully offloaded, it does
depend on the state of the network interfaces to operate. As such, the network
interface (e.g. eth0) associated with the FCoE offload initiator must be 'up'.
It is recommended that the network interfaces be configured to be brought up
automatically at boot time.

Furthermore, the Broadcom FCoE offload solution creates VLAN interfaces to
support the VLANs that have been discovered for FCoE operation (e.g.
eth0.1001-fcoe).  Do not delete or disable these interfaces or FCoE operation
will be disrupted.

Driver Usage Model:
===================

1. Ensure that fcoe-utils package is installed.

2. Configure the interfaces on which bnx2fc driver has to operate on.
Here are the steps to configure:

	a. cd /etc/fcoe
	b. copy cfg-ethx to cfg-eth5 if FCoE has to be enabled on eth5.
	c. Repeat this for all the interfaces where FCoE has to be enabled.
	d. Edit all the cfg-eth files to set "no" for DCB_REQUIRED** field, and
	   "yes" for AUTO_VLAN.
	e. Other configuration parameters should be left as default

3. Ensure that "bnx2fc" is in SUPPORTED_DRIVERS list in /etc/fcoe/config.

4. Start fcoe service. (service fcoe start). If Broadcom devices are present in
the system, bnx2fc driver would automatically claim the interfaces, starts vlan
discovery and log into the targets.

5. "Symbolic Name" in 'fcoeadm -i' output would display if bnx2fc has claimed
the interface.

Eg::

 [root@bh2 ~]# fcoeadm -i
    Description:      NetXtreme II BCM57712 10 Gigabit Ethernet
    Revision:         01
    Manufacturer:     Broadcom Corporation
    Serial Number:    0010186FD558
    Driver:           bnx2x 1.70.00-0
    Number of Ports:  2

        Symbolic Name:     bnx2fc v1.0.5 over eth5.4
        OS Device Name:    host11
        Node Name:         0x10000010186FD559
        Port Name:         0x20000010186FD559
        FabricName:        0x2001000DECB3B681
        Speed:             10 Gbit
        Supported Speed:   10 Gbit
        MaxFrameSize:      2048
        FC-ID (Port ID):   0x0F0377
        State:             Online

6. Verify the vlan discovery is performed by running ifconfig and notice
   <INTERFACE>.<VLAN>-fcoe interfaces are automatically created.

Refer to fcoeadm manpage for more information on fcoeadm operations to
create/destroy interfaces or to display lun/target information.

NOTE
====
** Broadcom FCoE capable devices implement a DCBX/LLDP client on-chip. Only one
LLDP client is allowed per interface. For proper operation all host software
based DCBX/LLDP clients (e.g. lldpad) must be disabled. To disable lldpad on a
given interface, run the following command::

	lldptool set-lldp -i <interface_name> adminStatus=disabled


code:
.. SPDX-License-Identifier: GPL-2.0

=================================
Chelsio S3 iSCSI Driver for Linux
=================================

Introduction
============

The Chelsio T3 ASIC based Adapters (S310, S320, S302, S304, Mezz cards, etc.
series of products) support iSCSI acceleration and iSCSI Direct Data Placement
(DDP) where the hardware handles the expensive byte touching operations, such
as CRC computation and verification, and direct DMA to the final host memory
destination:

	- iSCSI PDU digest generation and verification

	  On transmitting, Chelsio S3 h/w computes and inserts the Header and
	  Data digest into the PDUs.
	  On receiving, Chelsio S3 h/w computes and verifies the Header and
	  Data digest of the PDUs.

	- Direct Data Placement (DDP)

	  S3 h/w can directly place the iSCSI Data-In or Data-Out PDU's
	  payload into pre-posted final destination host-memory buffers based
	  on the Initiator Task Tag (ITT) in Data-In or Target Task Tag (TTT)
	  in Data-Out PDUs.

	- PDU Transmit and Recovery

	  On transmitting, S3 h/w accepts the complete PDU (header + data)
	  from the host driver, computes and inserts the digests, decomposes
	  the PDU into multiple TCP segments if necessary, and transmit all
	  the TCP segments onto the wire. It handles TCP retransmission if
	  needed.

	  On receiving, S3 h/w recovers the iSCSI PDU by reassembling TCP
	  segments, separating the header and data, calculating and verifying
	  the digests, then forwarding the header to the host. The payload data,
	  if possible, will be directly placed into the pre-posted host DDP
	  buffer. Otherwise, the payload data will be sent to the host too.

The cxgb3i driver interfaces with open-iscsi initiator and provides the iSCSI
acceleration through Chelsio hardware wherever applicable.

Using the cxgb3i Driver
=======================

The following steps need to be taken to accelerates the open-iscsi initiator:

1. Load the cxgb3i driver: "modprobe cxgb3i"

   The cxgb3i module registers a new transport class "cxgb3i" with open-iscsi.

   * in the case of recompiling the kernel, the cxgb3i selection is located at::

	Device Drivers
		SCSI device support --->
			[*] SCSI low-level drivers  --->
				<M>   Chelsio S3xx iSCSI support

2. Create an interface file located under /etc/iscsi/ifaces/ for the new
   transport class "cxgb3i".

   The content of the file should be in the following format::

	iface.transport_name = cxgb3i
	iface.net_ifacename = <ethX>
	iface.ipaddress = <iscsi ip address>

   * if iface.ipaddress is specified, <iscsi ip address> needs to be either the
     same as the ethX's ip address or an address on the same subnet. Make
     sure the ip address is unique in the network.

3. edit /etc/iscsi/iscsid.conf
   The default setting for MaxRecvDataSegmentLength (131072) is too big;
   replace with a value no bigger than 15360 (for example 8192)::

	node.conn[0].iscsi.MaxRecvDataSegmentLength = 8192

   * The login would fail for a normal session if MaxRecvDataSegmentLength is
     too big.  A error message in the format of
     "cxgb3i: ERR! MaxRecvSegmentLength <X> too big. Need to be <= <Y>."
     would be logged to dmesg.

4. To direct open-iscsi traffic to go through cxgb3i's accelerated path,
   "-I <iface file name>" option needs to be specified with most of the
   iscsiadm command. <iface file name> is the transport interface file created
   in step 2.


code:
.. SPDX-License-Identifier: GPL-2.0

======================================
README file for the dc395x SCSI driver
======================================

Status
------
The driver has been tested with CD-R and CD-R/W drives. These should
be safe to use. Testing with hard disks has not been done to any
great degree and caution should be exercised if you want to attempt
to use this driver with hard disks.

This is a 2.5 only driver. For a 2.4 driver please see the original
driver (which this driver started from) at
http://www.garloff.de/kurt/linux/dc395/

Problems, questions and patches should be submitted to the mailing
list. Details on the list, including archives, are available at
http://lists.twibble.org/mailman/listinfo/dc395x/

Parameters
----------
The driver uses the settings from the EEPROM set in the SCSI BIOS
setup. If there is no EEPROM, the driver uses default values.
Both can be overridden by command line parameters (module or kernel
parameters).

The following parameters are available:

safe
   Default: 0, Acceptable values: 0 or 1

   If safe is set to 1 then the adapter will use conservative
   ("safe") default settings. This sets:

		shortcut for dc395x=7,4,9,15,2,10

adapter_id
   Default: 7, Acceptable values: 0 to 15

   Sets the host adapter SCSI ID.

max_speed
   Default: 1, Acceptable value: 0 to 7

   ==  ========
   0   20   Mhz
   1   12.2 Mhz
   2   10   Mhz
   3   8    Mhz
   4   6.7  Mhz
   5   5.8  Hhz
   6   5    Mhz
   7   4    Mhz
   ==  ========

dev_mode
   Bitmap for device configuration

   DevMode bit definition:

      === ======== ========  =========================================
      Bit Val(hex) Val(dec)  Meaning
      === ======== ========  =========================================
       0    0x01       1     Parity check
       1    0x02       2     Synchronous Negotiation
       2    0x04       4     Disconnection
       3    0x08       8     Send Start command on startup. (Not used)
       4    0x10      16     Tagged Command Queueing
       5    0x20      32     Wide Negotiation
      === ======== ========  =========================================

adapter_mode
   Bitmap for adapter configuration

   AdaptMode bit definition

    ===== ======== ========  ====================================================
      Bit Val(hex) Val(dec)  Meaning
    ===== ======== ========  ====================================================
       0    0x01       1     Support more than two drives. (Not used)
       1    0x02       2     Use DOS compatible mapping for HDs greater than 1GB.
       2    0x04       4     Reset SCSI Bus on startup.
       3    0x08       8     Active Negation: Improves SCSI Bus noise immunity.
       4    0x10      16     Immediate return on BIOS seek command. (Not used)
    (*)5    0x20      32     Check for LUNs >= 1.
    ===== ======== ========  ====================================================

tags
   Default: 3, Acceptable values: 0-5

   The number of tags is 1<<x, if x has been specified

reset_delay
   Default: 1, Acceptable values: 0-180

   The seconds to not accept commands after a SCSI Reset

For the built  in driver the parameters should be prefixed with
dc395x. (eg "dc395x.safe=1")

Copyright
---------
The driver is free software. It is protected by the GNU General Public
License (GPL). Please read it, before using this driver. It should be
included in your kernel sources and with your distribution. It carries the
filename COPYING. If you don't have it, please ask me to send you one by
email.

Note: The GNU GPL says also something about warranty and liability.
Please be aware the following: While we do my best to provide a working and
reliable driver, there is a chance, that it will kill your valuable data.
We refuse to take any responsibility for that. The driver is provided as-is
and YOU USE IT AT YOUR OWN RESPONSIBILITY.


code:
.. SPDX-License-Identifier: GPL-2.0

===================
Adaptec dpti driver
===================

Redistribution and use in source form, with or without modification, are
permitted provided that redistributions of source code must retain the
above copyright notice, this list of conditions and the following disclaimer.

This software is provided ``as is`` by Adaptec and
any express or implied warranties, including, but not limited to, the
implied warranties of merchantability and fitness for a particular purpose,
are disclaimed. In no event shall Adaptec be
liable for any direct, indirect, incidental, special, exemplary or
consequential damages (including, but not limited to, procurement of
substitute goods or services; loss of use, data, or profits; or business
interruptions) however caused and on any theory of liability, whether in
contract, strict liability, or tort (including negligence or otherwise)
arising in any way out of the use of this driver software, even if advised
of the possibility of such damage.

This driver supports the Adaptec I2O RAID and DPT SmartRAID V I2O boards.

Credits
=======

The original linux driver was ported to Linux by Karen White while at
Dell Computer.  It was ported from Bob Pasteur's (of DPT) original
non-Linux driver.  Mark Salyzyn and Bob Pasteur consulted on the original
driver.

2.0 version of the driver by Deanna Bonds and Mark Salyzyn.

History
=======

The driver was originally ported to linux version 2.0.34

==== ==========================================================================
V2.0 Rewrite of driver.  Re-architectured based on i2o subsystem.
     This was the first full GPL version since the last version used
     i2osig headers which were not GPL.  Developer Testing version.
V2.1 Internal testing
V2.2 First released version

V2.3 Changes:

     - Added Raptor Support
     - Fixed bug causing system to hang under extreme load with
     - management utilities running (removed GFP_DMA from kmalloc flags)

V2.4 First version ready to be submitted to be embedded in the kernel

     Changes:

     - Implemented suggestions from Alan Cox
     - Added calculation of resid for sg layer
     - Better error handling
     - Added checking underflow conditions
     - Added DATAPROTECT checking
     - Changed error return codes
     - Fixed pointer bug in bus reset routine
     - Enabled hba reset from ioctls (allows a FW flash to reboot and use
       the new FW without having to reboot)
     - Changed proc output
==== ==========================================================================

TODO
====
- Add 64 bit Scatter Gather when compiled on 64 bit architectures
- Add sparse lun scanning
- Add code that checks if a device that had been taken offline is
  now online (at the FW level) when test unit ready or inquiry
  command from scsi-core
- Add proc read interface
- busrescan command
- rescan command
- Add code to rescan routine that notifies scsi-core about new devices
- Add support for C-PCI (hotplug stuff)
- Add ioctl passthru error recovery

Notes
=====
The DPT card optimizes the order of processing commands.  Consequently,
a command may take up to 6 minutes to complete after it has been sent
to the board.

The files dpti_ioctl.h dptsig.h osd_defs.h osd_util.h sys_info.h are part of the
interface files for Adaptec's management routines.  These define the structures used
in the ioctls.  They are written to be portable.  They are hard to read, but I need
to use them 'as is' or I can miss changes in the interface.


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

==========================================
README file for the Linux g_NCR5380 driver
==========================================

Copyright |copy| 1993 Drew Eckhard

NCR53c400 extensions Copyright |copy| 1994,1995,1996 Kevin Lentin

This file documents the NCR53c400 extensions by Kevin Lentin and some
enhancements to the NCR5380 core.

This driver supports NCR5380 and NCR53c400 and compatible cards in port or
memory mapped modes.

Use of an interrupt is recommended, if supported by the board, as this will
allow targets to disconnect and thereby improve SCSI bus utilization.

If the irq parameter is 254 or is omitted entirely, the driver will probe
for the correct IRQ line automatically. If the irq parameter is 0 or 255
then no IRQ will be used.

The NCR53c400 does not support DMA but it does have Pseudo-DMA which is
supported by the driver.

This driver provides some information on what it has detected in
/proc/scsi/g_NCR5380/x where x is the scsi card number as detected at boot
time. More info to come in the future.

This driver works as a module.
When included as a module, parameters can be passed on the insmod/modprobe
command line:

  ============= ===============================================================
  irq=xx[,...]	the interrupt(s)
  base=xx[,...]	the port or base address(es) (for port or memory mapped, resp.)
  card=xx[,...]	card type(s):

		==  ======================================
		0   NCR5380,
		1   NCR53C400,
		2   NCR53C400A,
		3   Domex Technology Corp 3181E (DTC3181E)
		4   Hewlett Packard C2502
		==  ======================================
  ============= ===============================================================

These old-style parameters can support only one card:

  ============= =================================================
  ncr_irq=xx    the interrupt
  ncr_addr=xx   the port or base address (for port or memory
                mapped, resp.)
  ncr_5380=1    to set up for a NCR5380 board
  ncr_53c400=1  to set up for a NCR53C400 board
  ncr_53c400a=1 to set up for a NCR53C400A board
  dtc_3181e=1   to set up for a Domex Technology Corp 3181E board
  hp_c2502=1    to set up for a Hewlett Packard C2502 board
  ============= =================================================

E.g. Trantor T130B in its default configuration::

	modprobe g_NCR5380 irq=5 base=0x350 card=1

or alternatively, using the old syntax::

	modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_53c400=1

E.g. a port mapped NCR5380 board, driver to probe for IRQ::

	modprobe g_NCR5380 base=0x350 card=0

or alternatively::

	modprobe g_NCR5380 ncr_addr=0x350 ncr_5380=1

E.g. a memory mapped NCR53C400 board with no IRQ::

	modprobe g_NCR5380 irq=255 base=0xc8000 card=1

or alternatively::

	modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1

E.g. two cards, DTC3181 (in non-PnP mode) at 0x240 with no IRQ
and HP C2502 at 0x300 with IRQ 7::

	modprobe g_NCR5380 irq=0,7 base=0x240,0x300 card=3,4

Kevin Lentin
K.Lentin@cs.monash.edu.au


code:
.. SPDX-License-Identifier: GPL-2.0

=========================================
HPSA - Hewlett Packard Smart Array driver
=========================================

This file describes the hpsa SCSI driver for HP Smart Array controllers.
The hpsa driver is intended to supplant the cciss driver for newer
Smart Array controllers.  The hpsa driver is a SCSI driver, while the
cciss driver is a "block" driver.  Actually cciss is both a block
driver (for logical drives) AND a SCSI driver (for tape drives). This
"split-brained" design of the cciss driver is a source of excess
complexity and eliminating that complexity is one of the reasons
for hpsa to exist.

Supported devices
=================

- Smart Array P212
- Smart Array P410
- Smart Array P410i
- Smart Array P411
- Smart Array P812
- Smart Array P712m
- Smart Array P711m
- StorageWorks P1210m

Additionally, older Smart Arrays may work with the hpsa driver if the kernel
boot parameter "hpsa_allow_any=1" is specified, however these are not tested
nor supported by HP with this driver.  For older Smart Arrays, the cciss
driver should still be used.

The "hpsa_simple_mode=1" boot parameter may be used to prevent the driver from
putting the controller into "performant" mode.  The difference is that with simple
mode, each command completion requires an interrupt, while with "performant mode"
(the default, and ordinarily better performing) it is possible to have multiple
command completions indicated by a single interrupt.

HPSA specific entries in /sys
=============================

  In addition to the generic SCSI attributes available in /sys, hpsa supports
  the following attributes:

HPSA specific host attributes
=============================

  ::

    /sys/class/scsi_host/host*/rescan
    /sys/class/scsi_host/host*/firmware_revision
    /sys/class/scsi_host/host*/resettable
    /sys/class/scsi_host/host*/transport_mode

  the host "rescan" attribute is a write only attribute.  Writing to this
  attribute will cause the driver to scan for new, changed, or removed devices
  (e.g. hot-plugged tape drives, or newly configured or deleted logical drives,
  etc.) and notify the SCSI midlayer of any changes detected.  Normally this is
  triggered automatically by HP's Array Configuration Utility (either the GUI or
  command line variety) so for logical drive changes, the user should not
  normally have to use this.  It may be useful when hot plugging devices like
  tape drives, or entire storage boxes containing pre-configured logical drives.

  The "firmware_revision" attribute contains the firmware version of the Smart Array.
  For example::

	root@host:/sys/class/scsi_host/host4# cat firmware_revision
	7.14

  The transport_mode indicates whether the controller is in "performant"
  or "simple" mode.  This is controlled by the "hpsa_simple_mode" module
  parameter.

  The "resettable" read-only attribute indicates whether a particular
  controller is able to honor the "reset_devices" kernel parameter.  If the
  device is resettable, this file will contain a "1", otherwise, a "0".  This
  parameter is used by kdump, for example, to reset the controller at driver
  load time to eliminate any outstanding commands on the controller and get the
  controller into a known state so that the kdump initiated i/o will work right
  and not be disrupted in any way by stale commands or other stale state
  remaining on the controller from the previous kernel.  This attribute enables
  kexec tools to warn the user if they attempt to designate a device which is
  unable to honor the reset_devices kernel parameter as a dump device.

HPSA specific disk attributes
-----------------------------

  ::

    /sys/class/scsi_disk/c:b:t:l/device/unique_id
    /sys/class/scsi_disk/c:b:t:l/device/raid_level
    /sys/class/scsi_disk/c:b:t:l/device/lunid

  (where c:b:t:l are the controller, bus, target and lun of the device)

  For example::

	root@host:/sys/class/scsi_disk/4:0:0:0/device# cat unique_id
	600508B1001044395355323037570F77
	root@host:/sys/class/scsi_disk/4:0:0:0/device# cat lunid
	0x0000004000000000
	root@host:/sys/class/scsi_disk/4:0:0:0/device# cat raid_level
	RAID 0

HPSA specific ioctls
====================

  For compatibility with applications written for the cciss driver, many, but
  not all of the ioctls supported by the cciss driver are also supported by the
  hpsa driver.  The data structures used by these are described in
  include/linux/cciss_ioctl.h

  CCISS_DEREGDISK, CCISS_REGNEWDISK, CCISS_REGNEWD
	The above three ioctls all do exactly the same thing, which is to cause the driver
	to rescan for new devices.  This does exactly the same thing as writing to the
	hpsa specific host "rescan" attribute.

  CCISS_GETPCIINFO
	Returns PCI domain, bus, device and function and "board ID" (PCI subsystem ID).

  CCISS_GETDRIVVER
	Returns driver version in three bytes encoded as::

		(major_version << 16) | (minor_version << 8) | (subminor_version)

  CCISS_PASSTHRU, CCISS_BIG_PASSTHRU
	Allows "BMIC" and "CISS" commands to be passed through to the Smart Array.
	These are used extensively by the HP Array Configuration Utility, SNMP storage
	agents, etc.  See cciss_vol_status at http://cciss.sf.net for some examples.


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

======================================================
Highpoint RocketRAID 3xxx/4xxx Adapter Driver (hptiop)
======================================================

Controller Register Map
-----------------------

For RR44xx Intel IOP based adapters, the controller IOP is accessed via PCI BAR0 and BAR2

     ============== ==================================
     BAR0 offset    Register
     ============== ==================================
            0x11C5C Link Interface IRQ Set
            0x11C60 Link Interface IRQ Clear
     ============== ==================================

     ============== ==================================
     BAR2 offset    Register
     ============== ==================================
            0x10    Inbound Message Register 0
            0x14    Inbound Message Register 1
            0x18    Outbound Message Register 0
            0x1C    Outbound Message Register 1
            0x20    Inbound Doorbell Register
            0x24    Inbound Interrupt Status Register
            0x28    Inbound Interrupt Mask Register
            0x30    Outbound Interrupt Status Register
            0x34    Outbound Interrupt Mask Register
            0x40    Inbound Queue Port
            0x44    Outbound Queue Port
     ============== ==================================

For Intel IOP based adapters, the controller IOP is accessed via PCI BAR0:

     ============== ==================================
     BAR0 offset    Register
     ============== ==================================
            0x10    Inbound Message Register 0
            0x14    Inbound Message Register 1
            0x18    Outbound Message Register 0
            0x1C    Outbound Message Register 1
            0x20    Inbound Doorbell Register
            0x24    Inbound Interrupt Status Register
            0x28    Inbound Interrupt Mask Register
            0x30    Outbound Interrupt Status Register
            0x34    Outbound Interrupt Mask Register
            0x40    Inbound Queue Port
            0x44    Outbound Queue Port
     ============== ==================================

For Marvell not Frey IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:

     ============== ==================================
     BAR0 offset    Register
     ============== ==================================
         0x20400    Inbound Doorbell Register
         0x20404    Inbound Interrupt Mask Register
         0x20408    Outbound Doorbell Register
         0x2040C    Outbound Interrupt Mask Register
     ============== ==================================

     ============== ==================================
     BAR1 offset    Register
     ============== ==================================
             0x0    Inbound Queue Head Pointer
             0x4    Inbound Queue Tail Pointer
             0x8    Outbound Queue Head Pointer
             0xC    Outbound Queue Tail Pointer
            0x10    Inbound Message Register
            0x14    Outbound Message Register
     0x40-0x1040    Inbound Queue
     0x1040-0x2040  Outbound Queue
     ============== ==================================

For Marvell Frey IOP based adapters, the IOP is accessed via PCI BAR0 and BAR1:

     ============== ==================================
     BAR0 offset    Register
     ============== ==================================
             0x0    IOP configuration information.
     ============== ==================================

     ============== ===================================================
     BAR1 offset    Register
     ============== ===================================================
          0x4000    Inbound List Base Address Low
          0x4004    Inbound List Base Address High
          0x4018    Inbound List Write Pointer
          0x402C    Inbound List Configuration and Control
          0x4050    Outbound List Base Address Low
          0x4054    Outbound List Base Address High
          0x4058    Outbound List Copy Pointer Shadow Base Address Low
          0x405C    Outbound List Copy Pointer Shadow Base Address High
          0x4088    Outbound List Interrupt Cause
          0x408C    Outbound List Interrupt Enable
         0x1020C    PCIe Function 0 Interrupt Enable
         0x10400    PCIe Function 0 to CPU Message A
         0x10420    CPU to PCIe Function 0 Message A
         0x10480    CPU to PCIe Function 0 Doorbell
         0x10484    CPU to PCIe Function 0 Doorbell Enable
     ============== ===================================================

I/O Request Workflow of Not Marvell Frey
----------------------------------------

All queued requests are handled via inbound/outbound queue port.
A request packet can be allocated in either IOP or host memory.

To send a request to the controller:

    - Get a free request packet by reading the inbound queue port or
      allocate a free request in host DMA coherent memory.

      The value returned from the inbound queue port is an offset
      relative to the IOP BAR0.

      Requests allocated in host memory must be aligned on 32-bytes boundary.

    - Fill the packet.

    - Post the packet to IOP by writing it to inbound queue. For requests
      allocated in IOP memory, write the offset to inbound queue port. For
      requests allocated in host memory, write (0x80000000|(bus_addr>>5))
      to the inbound queue port.

    - The IOP process the request. When the request is completed, it
      will be put into outbound queue. An outbound interrupt will be
      generated.

      For requests allocated in IOP memory, the request offset is posted to
      outbound queue.

      For requests allocated in host memory, (0x80000000|(bus_addr>>5))
      is posted to the outbound queue. If IOP_REQUEST_FLAG_OUTPUT_CONTEXT
      flag is set in the request, the low 32-bit context value will be
      posted instead.

    - The host read the outbound queue and complete the request.

      For requests allocated in IOP memory, the host driver free the request
      by writing it to the outbound queue.

Non-queued requests (reset/flush etc) can be sent via inbound message
register 0. An outbound message with the same value indicates the completion
of an inbound message.

I/O Request Workflow of Marvell Frey
------------------------------------

All queued requests are handled via inbound/outbound list.

To send a request to the controller:

    - Allocate a free request in host DMA coherent memory.

      Requests allocated in host memory must be aligned on 32-bytes boundary.

    - Fill the request with index of the request in the flag.

      Fill a free inbound list unit with the physical address and the size of
      the request.

      Set up the inbound list write pointer with the index of previous unit,
      round to 0 if the index reaches the supported count of requests.

    - Post the inbound list writer pointer to IOP.

    - The IOP process the request. When the request is completed, the flag of
      the request with or-ed IOPMU_QUEUE_MASK_HOST_BITS will be put into a
      free outbound list unit and the index of the outbound list unit will be
      put into the copy pointer shadow register. An outbound interrupt will be
      generated.

    - The host read the outbound list copy pointer shadow register and compare
      with previous saved read pointer N. If they are different, the host will
      read the (N+1)th outbound list unit.

      The host get the index of the request from the (N+1)th outbound list
      unit and complete the request.

Non-queued requests (reset communication/reset/flush etc) can be sent via PCIe
Function 0 to CPU Message A register. The CPU to PCIe Function 0 Message register
with the same value indicates the completion of message.

User-level Interface
---------------------

The driver exposes following sysfs attributes:

     ==================   ===    ========================
     NAME                 R/W    Description
     ==================   ===    ========================
     driver-version        R     driver version string
     firmware-version      R     firmware version string
     ==================   ===    ========================

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

Copyright |copy| 2006-2012 HighPoint Technologies, Inc. All Rights Reserved.

  This file 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.

  linux@highpoint-tech.com

  http://www.highpoint-tech.com


code:
.. SPDX-License-Identifier: GPL-2.0

====================
Linux SCSI Subsystem
====================

.. toctree::
   :maxdepth: 1

   53c700
   aacraid
   advansys
   aha152x
   aic79xx
   aic7xxx
   arcmsr_spec
   bfa
   bnx2fc
   BusLogic
   cxgb3i
   dc395x
   dpti
   FlashPoint
   g_NCR5380
   hpsa
   hptiop
   libsas
   link_power_management_policy
   lpfc
   megaraid
   ncr53c8xx
   NinjaSCSI
   ppa
   qlogicfas
   scsi-changer
   scsi_eh
   scsi_fc_transport
   scsi-generic
   scsi_mid_low_api
   scsi-parameters
   scsi
   sd-parameters
   smartpqi
   st
   sym53c500_cs
   sym53c8xx_2
   tcm_qla2xxx
   ufs
   wd719x

   scsi_transport_srp/figures


code:
.. SPDX-License-Identifier: GPL-2.0

=========
SAS Layer
=========

The SAS Layer is a management infrastructure which manages
SAS LLDDs.  It sits between SCSI Core and SAS LLDDs.  The
layout is as follows: while SCSI Core is concerned with
SAM/SPC issues, and a SAS LLDD+sequencer is concerned with
phy/OOB/link management, the SAS layer is concerned with:

      * SAS Phy/Port/HA event management (LLDD generates,
        SAS Layer processes),
      * SAS Port management (creation/destruction),
      * SAS Domain discovery and revalidation,
      * SAS Domain device management,
      * SCSI Host registration/unregistration,
      * Device registration with SCSI Core (SAS) or libata
        (SATA), and
      * Expander management and exporting expander control
        to user space.

A SAS LLDD is a PCI device driver.  It is concerned with
phy/OOB management, and vendor specific tasks and generates
events to the SAS layer.

The SAS Layer does most SAS tasks as outlined in the SAS 1.1
spec.

The sas_ha_struct describes the SAS LLDD to the SAS layer.
Most of it is used by the SAS Layer but a few fields need to
be initialized by the LLDDs.

After initializing your hardware, from the probe() function
you call sas_register_ha(). It will register your LLDD with
the SCSI subsystem, creating a SCSI host and it will
register your SAS driver with the sysfs SAS tree it creates.
It will then return.  Then you enable your phys to actually
start OOB (at which point your driver will start calling the
notify_* event callbacks).

Structure descriptions
======================

``struct sas_phy``
------------------

Normally this is statically embedded to your driver's
phy structure::

    struct my_phy {
	    blah;
	    struct sas_phy sas_phy;
	    bleh;
    };

And then all the phys are an array of my_phy in your HA
struct (shown below).

Then as you go along and initialize your phys you also
initialize the sas_phy struct, along with your own
phy structure.

In general, the phys are managed by the LLDD and the ports
are managed by the SAS layer.  So the phys are initialized
and updated by the LLDD and the ports are initialized and
updated by the SAS layer.

There is a scheme where the LLDD can RW certain fields,
and the SAS layer can only read such ones, and vice versa.
The idea is to avoid unnecessary locking.

enabled
    - must be set (0/1)

id
    - must be set [0,MAX_PHYS)]

class, proto, type, role, oob_mode, linkrate
    - must be set

oob_mode
    - you set this when OOB has finished and then notify
      the SAS Layer.

sas_addr
    - this normally points to an array holding the sas
      address of the phy, possibly somewhere in your my_phy
      struct.

attached_sas_addr
    - set this when you (LLDD) receive an
      IDENTIFY frame or a FIS frame, _before_ notifying the SAS
      layer.  The idea is that sometimes the LLDD may want to fake
      or provide a different SAS address on that phy/port and this
      allows it to do this.  At best you should copy the sas
      address from the IDENTIFY frame or maybe generate a SAS
      address for SATA directly attached devices.  The Discover
      process may later change this.

frame_rcvd
    - this is where you copy the IDENTIFY/FIS frame
      when you get it; you lock, copy, set frame_rcvd_size and
      unlock the lock, and then call the event.  It is a pointer
      since there's no way to know your hw frame size _exactly_,
      so you define the actual array in your phy struct and let
      this pointer point to it.  You copy the frame from your
      DMAable memory to that area holding the lock.

sas_prim
    - this is where primitives go when they're
      received.  See sas.h. Grab the lock, set the primitive,
      release the lock, notify.

port
    - this points to the sas_port if the phy belongs
      to a port -- the LLDD only reads this. It points to the
      sas_port this phy is part of.  Set by the SAS Layer.

ha
    - may be set; the SAS layer sets it anyway.

lldd_phy
    - you should set this to point to your phy so you
      can find your way around faster when the SAS layer calls one
      of your callbacks and passes you a phy.  If the sas_phy is
      embedded you can also use container_of -- whatever you
      prefer.

``struct sas_port``
-------------------

The LLDD doesn't set any fields of this struct -- it only
reads them.  They should be self explanatory.

phy_mask is 32 bit, this should be enough for now, as I
haven't heard of a HA having more than 8 phys.

lldd_port
    - I haven't found use for that -- maybe other
      LLDD who wish to have internal port representation can make
      use of this.

``struct sas_ha_struct``
------------------------

It normally is statically declared in your own LLDD
structure describing your adapter::

    struct my_sas_ha {
	blah;
	struct sas_ha_struct sas_ha;
	struct my_phy phys[MAX_PHYS];
	struct sas_port sas_ports[MAX_PHYS]; /* (1) */
	bleh;
    };

    (1) If your LLDD doesn't have its own port representation.

What needs to be initialized (sample function given below).

pcidev
^^^^^^

sas_addr
       - since the SAS layer doesn't want to mess with
	 memory allocation, etc, this points to statically
	 allocated array somewhere (say in your host adapter
	 structure) and holds the SAS address of the host
	 adapter as given by you or the manufacturer, etc.

sas_port
^^^^^^^^

sas_phy
      - an array of pointers to structures. (see
	note above on sas_addr).
	These must be set.  See more notes below.

num_phys
       - the number of phys present in the sas_phy array,
	 and the number of ports present in the sas_port
	 array.  There can be a maximum num_phys ports (one per
	 port) so we drop the num_ports, and only use
	 num_phys.

The event interface::

	/* LLDD calls these to notify the class of an event. */
	void sas_notify_port_event(struct sas_phy *, enum port_event, gfp_t);
	void sas_notify_phy_event(struct sas_phy *, enum phy_event, gfp_t);

The port notification::

	/* The class calls these to notify the LLDD of an event. */
	void (*lldd_port_formed)(struct sas_phy *);
	void (*lldd_port_deformed)(struct sas_phy *);

If the LLDD wants notification when a port has been formed
or deformed it sets those to a function satisfying the type.

A SAS LLDD should also implement at least one of the Task
Management Functions (TMFs) described in SAM::

	/* Task Management Functions. Must be called from process context. */
	int (*lldd_abort_task)(struct sas_task *);
	int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
	int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
	int (*lldd_I_T_nexus_reset)(struct domain_device *);
	int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
	int (*lldd_query_task)(struct sas_task *);

For more information please read SAM from T10.org.

Port and Adapter management::

	/* Port and Adapter management */
	int (*lldd_clear_nexus_port)(struct sas_port *);
	int (*lldd_clear_nexus_ha)(struct sas_ha_struct *);

A SAS LLDD should implement at least one of those.

Phy management::

	/* Phy management */
	int (*lldd_control_phy)(struct sas_phy *, enum phy_func);

lldd_ha
    - set this to point to your HA struct. You can also
      use container_of if you embedded it as shown above.

A sample initialization and registration function
can look like this (called last thing from probe())
*but* before you enable the phys to do OOB::

    static int register_sas_ha(struct my_sas_ha *my_ha)
    {
	    int i;
	    static struct sas_phy   *sas_phys[MAX_PHYS];
	    static struct sas_port  *sas_ports[MAX_PHYS];

	    my_ha->sas_ha.sas_addr = &my_ha->sas_addr[0];

	    for (i = 0; i < MAX_PHYS; i++) {
		    sas_phys[i] = &my_ha->phys[i].sas_phy;
		    sas_ports[i] = &my_ha->sas_ports[i];
	    }

	    my_ha->sas_ha.sas_phy  = sas_phys;
	    my_ha->sas_ha.sas_port = sas_ports;
	    my_ha->sas_ha.num_phys = MAX_PHYS;

	    my_ha->sas_ha.lldd_port_formed = my_port_formed;

	    my_ha->sas_ha.lldd_dev_found = my_dev_found;
	    my_ha->sas_ha.lldd_dev_gone = my_dev_gone;

	    my_ha->sas_ha.lldd_execute_task = my_execute_task;

	    my_ha->sas_ha.lldd_abort_task     = my_abort_task;
	    my_ha->sas_ha.lldd_abort_task_set = my_abort_task_set;
	    my_ha->sas_ha.lldd_clear_task_set = my_clear_task_set;
	    my_ha->sas_ha.lldd_I_T_nexus_reset= NULL; (2)
	    my_ha->sas_ha.lldd_lu_reset       = my_lu_reset;
	    my_ha->sas_ha.lldd_query_task     = my_query_task;

	    my_ha->sas_ha.lldd_clear_nexus_port = my_clear_nexus_port;
	    my_ha->sas_ha.lldd_clear_nexus_ha = my_clear_nexus_ha;

	    my_ha->sas_ha.lldd_control_phy = my_control_phy;

	    return sas_register_ha(&my_ha->sas_ha);
    }

(2) SAS 1.1 does not define I_T Nexus Reset TMF.

Events
======

Events are **the only way** a SAS LLDD notifies the SAS layer
of anything.  There is no other method or way a LLDD to tell
the SAS layer of anything happening internally or in the SAS
domain.

Phy events::

	PHYE_LOSS_OF_SIGNAL, (C)
	PHYE_OOB_DONE,
	PHYE_OOB_ERROR,      (C)
	PHYE_SPINUP_HOLD.

Port events, passed on a _phy_::

	PORTE_BYTES_DMAED,      (M)
	PORTE_BROADCAST_RCVD,   (E)
	PORTE_LINK_RESET_ERR,   (C)
	PORTE_TIMER_EVENT,      (C)
	PORTE_HARD_RESET.

Host Adapter event:
	HAE_RESET

A SAS LLDD should be able to generate

	- at least one event from group C (choice),
	- events marked M (mandatory) are mandatory (only one),
	- events marked E (expander) if it wants the SAS layer
	  to handle domain revalidation (only one such).
	- Unmarked events are optional.

Meaning:

HAE_RESET
    - when your HA got internal error and was reset.

PORTE_BYTES_DMAED
    - on receiving an IDENTIFY/FIS frame

PORTE_BROADCAST_RCVD
    - on receiving a primitive

PORTE_LINK_RESET_ERR
    - timer expired, loss of signal, loss of DWS, etc. [1]_

PORTE_TIMER_EVENT
    - DWS reset timeout timer expired [1]_

PORTE_HARD_RESET
    - Hard Reset primitive received.

PHYE_LOSS_OF_SIGNAL
    - the device is gone [1]_

PHYE_OOB_DONE
    - OOB went fine and oob_mode is valid

PHYE_OOB_ERROR
    - Error while doing OOB, the device probably
      got disconnected. [1]_

PHYE_SPINUP_HOLD
    - SATA is present, COMWAKE not sent.

.. [1] should set/clear the appropriate fields in the phy,
       or alternatively call the inlined sas_phy_disconnected()
       which is just a helper, from their tasklet.

The Execute Command SCSI RPC::

	int (*lldd_execute_task)(struct sas_task *, gfp_t gfp_flags);

Used to queue a task to the SAS LLDD.  @task is the task to be executed.
@gfp_mask is the gfp_mask defining the context of the caller.

This function should implement the Execute Command SCSI RPC,

That is, when lldd_execute_task() is called, the command
go out on the transport *immediately*.  There is *no*
queuing of any sort and at any level in a SAS LLDD.

Returns:

   * -SAS_QUEUE_FULL, -ENOMEM, nothing was queued;
   * 0, the task(s) were queued.

::

    struct sas_task {
	    dev -- the device this task is destined to
	    task_proto -- _one_ of enum sas_proto
	    scatter -- pointer to scatter gather list array
	    num_scatter -- number of elements in scatter
	    total_xfer_len -- total number of bytes expected to be transferred
	    data_dir -- PCI_DMA_...
	    task_done -- callback when the task has finished execution
    };

Discovery
=========

The sysfs tree has the following purposes:

    a) It shows you the physical layout of the SAS domain at
       the current time, i.e. how the domain looks in the
       physical world right now.
    b) Shows some device parameters _at_discovery_time_.

This is a link to the tree(1) program, very useful in
viewing the SAS domain:
ftp://mama.indstate.edu/linux/tree/

I expect user space applications to actually create a
graphical interface of this.

That is, the sysfs domain tree doesn't show or keep state if
you e.g., change the meaning of the READY LED MEANING
setting, but it does show you the current connection status
of the domain device.

Keeping internal device state changes is responsibility of
upper layers (Command set drivers) and user space.

When a device or devices are unplugged from the domain, this
is reflected in the sysfs tree immediately, and the device(s)
removed from the system.

The structure domain_device describes any device in the SAS
domain.  It is completely managed by the SAS layer.  A task
points to a domain device, this is how the SAS LLDD knows
where to send the task(s) to.  A SAS LLDD only reads the
contents of the domain_device structure, but it never creates
or destroys one.

Expander management from User Space
===================================

In each expander directory in sysfs, there is a file called
"smp_portal".  It is a binary sysfs attribute file, which
implements an SMP portal (Note: this is *NOT* an SMP port),
to which user space applications can send SMP requests and
receive SMP responses.

Functionality is deceptively simple:

1. Build the SMP frame you want to send. The format and layout
   is described in the SAS spec.  Leave the CRC field equal 0.

open(2)

2. Open the expander's SMP portal sysfs file in RW mode.

write(2)

3. Write the frame you built in 1.

read(2)

4. Read the amount of data you expect to receive for the frame you built.
   If you receive different amount of data you expected to receive,
   then there was some kind of error.

close(2)

All this process is shown in detail in the function do_smp_func()
and its callers, in the file "expander_conf.c".

The kernel functionality is implemented in the file
"sas_expander.c".

The program "expander_conf.c" implements this. It takes one
argument, the sysfs file name of the SMP portal to the
expander, and gives expander information, including routing
tables.

The SMP portal gives you complete control of the expander,
so please be careful.


code:
.. SPDX-License-Identifier: GPL-2.0

==========================
Link Power Managent Policy
==========================

This parameter allows the user to set the link (interface) power management.
There are 3 possible options:

=====================   =====================================================
Value			Effect
=====================   =====================================================
min_power		Tell the controller to try to make the link use the
			least possible power when possible.  This may
			sacrifice some performance due to increased latency
			when coming out of lower power states.

max_performance		Generally, this means no power management.  Tell
			the controller to have performance be a priority
			over power management.

medium_power		Tell the controller to enter a lower power state
			when possible, but do not enter the lowest power
			state, thus improving latency over min_power setting.
=====================   =====================================================


code:
.. SPDX-License-Identifier: GPL-2.0

=========================
LPFC Driver Release Notes
=========================

.. important::

  Starting in the 8.0.17 release, the driver began to be targeted strictly
  toward the upstream kernel. As such, we removed #ifdefs for older kernels
  (pre 2.6.10). The 8.0.16 release should be used if the driver is to be
  run on one of the older kernels.

  The proposed modifications to the transport layer for FC remote ports
  and extended attribute support is now part of the upstream kernel
  as of 2.6.12. We no longer need to provide patches for this support,
  nor a *full* version which has old an new kernel support.

  The driver now requires a 2.6.12 (if pre-release, 2.6.12-rc1) or later
  kernel.

  Please heed these dependencies....

The following information is provided for additional background on the
history of the driver as we push for upstream acceptance.

Cable pull and temporary device Loss:

  In older revisions of the lpfc driver, the driver internally queued i/o
  received from the midlayer. In the cases where a cable was pulled, link
  jitter, or a device temporarily loses connectivity (due to its cable
  being removed, a switch rebooting, or a device reboot), the driver could
  hide the disappearance of the device from the midlayer. I/O's issued to
  the LLDD would simply be queued for a short duration, allowing the device
  to reappear or link come back alive, with no inadvertent side effects
  to the system. If the driver did not hide these conditions, i/o would be
  errored by the driver, the mid-layer would exhaust its retries, and the
  device would be taken offline. Manual intervention would be required to
  re-enable the device.

  The community supporting kernel.org has driven an effort to remove
  internal queuing from all LLDDs. The philosophy is that internal
  queuing is unnecessary as the block layer already performs the
  queuing. Removing the queues from the LLDD makes a more predictable
  and more simple LLDD.

  As a potential new addition to kernel.org, the 8.x driver was asked to
  have all internal queuing removed. Emulex complied with this request.
  In explaining the impacts of this change, Emulex has worked with the
  community in modifying the behavior of the SCSI midlayer so that SCSI
  devices can be temporarily suspended while transport events (such as
  those described) can occur.

  The proposed patch was posted to the linux-scsi mailing list. The patch
  is contained in the 2.6.10-rc2 (and later) patch kits. As such, this
  patch is part of the standard 2.6.10 kernel.

  By default, the driver expects the patches for block/unblock interfaces
  to be present in the kernel. No #define needs to be set to enable support.

Kernel Support
==============

  This source package is targeted for the upstream kernel only. (See notes
  at the top of this file). It relies on interfaces that are slowing
  migrating into the kernel.org kernel.

  At this time, the driver requires the 2.6.12 (if pre-release, 2.6.12-rc1)
  kernel.

  If a driver is needed for older kernels please utilize the 8.0.16
  driver sources.

Patches
=======

  Thankfully, at this time, patches are not needed.


code:
.. SPDX-License-Identifier: GPL-2.0

==========================
Notes on Management Module
==========================

Overview
--------

Different classes of controllers from LSI Logic accept and respond to the
user applications in a similar way. They understand the same firmware control
commands. Furthermore, the applications also can treat different classes of
the controllers uniformly. Hence it is logical to have a single module that
interfaces with the applications on one side and all the low level drivers
on the other.

The advantages, though obvious, are listed for completeness:

	i.	Avoid duplicate code from the low level drivers.
	ii.	Unburden the low level drivers from having to export the
		character node device and related handling.
	iii.	Implement any policy mechanisms in one place.
	iv.	Applications have to interface with only module instead of
		multiple low level drivers.

Currently this module (called Common Management Module) is used only to issue
ioctl commands. But this module is envisioned to handle all user space level
interactions. So any 'proc', 'sysfs' implementations will be localized in this
common module.

Credits
-------

::

	"Shared code in a third module, a "library module", is an acceptable
	solution. modprobe automatically loads dependent modules, so users
	running "modprobe driver1" or "modprobe driver2" would automatically
	load the shared library module."

- Jeff Garzik (jgarzik@pobox.com), 02.25.2004 LKML

::

	"As Jeff hinted, if your userspace<->driver API is consistent between
	your new MPT-based RAID controllers and your existing megaraid driver,
	then perhaps you need a single small helper module (lsiioctl or some
	better name), loaded by both mptraid and megaraid automatically, which
	handles registering the /dev/megaraid node dynamically. In this case,
	both mptraid and megaraid would register with lsiioctl for each
	adapter discovered, and lsiioctl would essentially be a switch,
	redirecting userspace tool ioctls to the appropriate driver."

- Matt Domsch, (Matt_Domsch@dell.com), 02.25.2004 LKML

Design
------

The Common Management Module is implemented in megaraid_mm.[ch] files. This
module acts as a registry for low level hba drivers. The low level drivers
(currently only megaraid) register each controller with the common module.

The applications interface with the common module via the character device
node exported by the module.

The lower level drivers now understand only a new improved ioctl packet called
uioc_t. The management module converts the older ioctl packets from the older
applications into uioc_t. After driver handles the uioc_t, the common module
will convert that back into the old format before returning to applications.

As new applications evolve and replace the old ones, the old packet format
will be retired.

Common module dedicates one uioc_t packet to each controller registered. This
can easily be more than one. But since megaraid is the only low level driver
today, and it can handle only one ioctl, there is no reason to have more. But
as new controller classes get added, this will be tuned appropriately.