xref: /linux/drivers/scsi/3w-9xxx.h (revision 762f99f4f3cb41a775b5157dd761217beba65873)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux.
31da177e4SLinus Torvalds 
42c9bce5bSadam radford    Written By: Adam Radford <aradford@gmail.com>
52c9bce5bSadam radford    Modifications By: Tom Couch
61da177e4SLinus Torvalds 
77a252fe7Sadam radford    Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
84deedd84Sadam radford    Copyright (C) 2010 LSI Corporation.
91da177e4SLinus Torvalds 
101da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
111da177e4SLinus Torvalds    it under the terms of the GNU General Public License as published by
121da177e4SLinus Torvalds    the Free Software Foundation; version 2 of the License.
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds    This program is distributed in the hope that it will be useful,
151da177e4SLinus Torvalds    but WITHOUT ANY WARRANTY; without even the implied warranty of
161da177e4SLinus Torvalds    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
171da177e4SLinus Torvalds    GNU General Public License for more details.
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds    NO WARRANTY
201da177e4SLinus Torvalds    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
211da177e4SLinus Torvalds    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
221da177e4SLinus Torvalds    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
231da177e4SLinus Torvalds    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
241da177e4SLinus Torvalds    solely responsible for determining the appropriateness of using and
251da177e4SLinus Torvalds    distributing the Program and assumes all risks associated with its
261da177e4SLinus Torvalds    exercise of rights under this Agreement, including but not limited to
271da177e4SLinus Torvalds    the risks and costs of program errors, damage to or loss of data,
281da177e4SLinus Torvalds    programs or equipment, and unavailability or interruption of operations.
291da177e4SLinus Torvalds 
301da177e4SLinus Torvalds    DISCLAIMER OF LIABILITY
311da177e4SLinus Torvalds    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
321da177e4SLinus Torvalds    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
331da177e4SLinus Torvalds    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
341da177e4SLinus Torvalds    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
351da177e4SLinus Torvalds    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
361da177e4SLinus Torvalds    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
371da177e4SLinus Torvalds    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
381da177e4SLinus Torvalds 
391da177e4SLinus Torvalds    You should have received a copy of the GNU General Public License
401da177e4SLinus Torvalds    along with this program; if not, write to the Free Software
411da177e4SLinus Torvalds    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds    Bugs/Comments/Suggestions should be mailed to:
442c9bce5bSadam radford    aradford@gmail.com
451da177e4SLinus Torvalds */
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds #ifndef _3W_9XXX_H
481da177e4SLinus Torvalds #define _3W_9XXX_H
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds /* AEN string type */
511da177e4SLinus Torvalds typedef struct TAG_twa_message_type {
521da177e4SLinus Torvalds 	unsigned int   code;
531da177e4SLinus Torvalds 	char           *text;
541da177e4SLinus Torvalds } twa_message_type;
551da177e4SLinus Torvalds 
561da177e4SLinus Torvalds /* AEN strings */
571da177e4SLinus Torvalds static twa_message_type twa_aen_table[] = {
581da177e4SLinus Torvalds 	{0x0000, "AEN queue empty"},
591da177e4SLinus Torvalds 	{0x0001, "Controller reset occurred"},
601da177e4SLinus Torvalds 	{0x0002, "Degraded unit detected"},
6125985edcSLucas De Marchi 	{0x0003, "Controller error occurred"},
621da177e4SLinus Torvalds 	{0x0004, "Background rebuild failed"},
631da177e4SLinus Torvalds 	{0x0005, "Background rebuild done"},
641da177e4SLinus Torvalds 	{0x0006, "Incomplete unit detected"},
651da177e4SLinus Torvalds 	{0x0007, "Background initialize done"},
661da177e4SLinus Torvalds 	{0x0008, "Unclean shutdown detected"},
671da177e4SLinus Torvalds 	{0x0009, "Drive timeout detected"},
681da177e4SLinus Torvalds 	{0x000A, "Drive error detected"},
691da177e4SLinus Torvalds 	{0x000B, "Rebuild started"},
701da177e4SLinus Torvalds 	{0x000C, "Background initialize started"},
711da177e4SLinus Torvalds 	{0x000D, "Entire logical unit was deleted"},
721da177e4SLinus Torvalds 	{0x000E, "Background initialize failed"},
731da177e4SLinus Torvalds 	{0x000F, "SMART attribute exceeded threshold"},
741da177e4SLinus Torvalds 	{0x0010, "Power supply reported AC under range"},
751da177e4SLinus Torvalds 	{0x0011, "Power supply reported DC out of range"},
761da177e4SLinus Torvalds 	{0x0012, "Power supply reported a malfunction"},
771da177e4SLinus Torvalds 	{0x0013, "Power supply predicted malfunction"},
781da177e4SLinus Torvalds 	{0x0014, "Battery charge is below threshold"},
791da177e4SLinus Torvalds 	{0x0015, "Fan speed is below threshold"},
801da177e4SLinus Torvalds 	{0x0016, "Temperature sensor is above threshold"},
811da177e4SLinus Torvalds 	{0x0017, "Power supply was removed"},
821da177e4SLinus Torvalds 	{0x0018, "Power supply was inserted"},
831da177e4SLinus Torvalds 	{0x0019, "Drive was removed from a bay"},
841da177e4SLinus Torvalds 	{0x001A, "Drive was inserted into a bay"},
851da177e4SLinus Torvalds 	{0x001B, "Drive bay cover door was opened"},
861da177e4SLinus Torvalds 	{0x001C, "Drive bay cover door was closed"},
871da177e4SLinus Torvalds 	{0x001D, "Product case was opened"},
881da177e4SLinus Torvalds 	{0x0020, "Prepare for shutdown (power-off)"},
891da177e4SLinus Torvalds 	{0x0021, "Downgrade UDMA mode to lower speed"},
901da177e4SLinus Torvalds 	{0x0022, "Upgrade UDMA mode to higher speed"},
911da177e4SLinus Torvalds 	{0x0023, "Sector repair completed"},
921da177e4SLinus Torvalds 	{0x0024, "Sbuf memory test failed"},
931da177e4SLinus Torvalds 	{0x0025, "Error flushing cached write data to array"},
941da177e4SLinus Torvalds 	{0x0026, "Drive reported data ECC error"},
951da177e4SLinus Torvalds 	{0x0027, "DCB has checksum error"},
961da177e4SLinus Torvalds 	{0x0028, "DCB version is unsupported"},
971da177e4SLinus Torvalds 	{0x0029, "Background verify started"},
981da177e4SLinus Torvalds 	{0x002A, "Background verify failed"},
991da177e4SLinus Torvalds 	{0x002B, "Background verify done"},
1001da177e4SLinus Torvalds 	{0x002C, "Bad sector overwritten during rebuild"},
1011da177e4SLinus Torvalds 	{0x002D, "Background rebuild error on source drive"},
1021da177e4SLinus Torvalds 	{0x002E, "Replace failed because replacement drive too small"},
1031da177e4SLinus Torvalds 	{0x002F, "Verify failed because array was never initialized"},
1041da177e4SLinus Torvalds 	{0x0030, "Unsupported ATA drive"},
1051da177e4SLinus Torvalds 	{0x0031, "Synchronize host/controller time"},
1061da177e4SLinus Torvalds 	{0x0032, "Spare capacity is inadequate for some units"},
1071da177e4SLinus Torvalds 	{0x0033, "Background migration started"},
1081da177e4SLinus Torvalds 	{0x0034, "Background migration failed"},
1091da177e4SLinus Torvalds 	{0x0035, "Background migration done"},
1101da177e4SLinus Torvalds 	{0x0036, "Verify detected and fixed data/parity mismatch"},
1111da177e4SLinus Torvalds 	{0x0037, "SO-DIMM incompatible"},
1121da177e4SLinus Torvalds 	{0x0038, "SO-DIMM not detected"},
1131da177e4SLinus Torvalds 	{0x0039, "Corrected Sbuf ECC error"},
1141da177e4SLinus Torvalds 	{0x003A, "Drive power on reset detected"},
1151da177e4SLinus Torvalds 	{0x003B, "Background rebuild paused"},
1161da177e4SLinus Torvalds 	{0x003C, "Background initialize paused"},
1171da177e4SLinus Torvalds 	{0x003D, "Background verify paused"},
1181da177e4SLinus Torvalds 	{0x003E, "Background migration paused"},
1191da177e4SLinus Torvalds 	{0x003F, "Corrupt flash file system detected"},
1201da177e4SLinus Torvalds 	{0x0040, "Flash file system repaired"},
1211da177e4SLinus Torvalds 	{0x0041, "Unit number assignments were lost"},
1221da177e4SLinus Torvalds 	{0x0042, "Error during read of primary DCB"},
1231da177e4SLinus Torvalds 	{0x0043, "Latent error found in backup DCB"},
1241da177e4SLinus Torvalds 	{0x00FC, "Recovered/finished array membership update"},
1251da177e4SLinus Torvalds 	{0x00FD, "Handler lockup"},
1261da177e4SLinus Torvalds 	{0x00FE, "Retrying PCI transfer"},
1271da177e4SLinus Torvalds 	{0x00FF, "AEN queue is full"},
1281da177e4SLinus Torvalds 	{0xFFFFFFFF, (char*) 0}
1291da177e4SLinus Torvalds };
1301da177e4SLinus Torvalds 
1311da177e4SLinus Torvalds /* AEN severity table */
1321da177e4SLinus Torvalds static char *twa_aen_severity_table[] =
1331da177e4SLinus Torvalds {
1341da177e4SLinus Torvalds 	"None", "ERROR", "WARNING", "INFO", "DEBUG", (char*) 0
1351da177e4SLinus Torvalds };
1361da177e4SLinus Torvalds 
1371da177e4SLinus Torvalds /* Error strings */
1381da177e4SLinus Torvalds static twa_message_type twa_error_table[] = {
1391da177e4SLinus Torvalds 	{0x0100, "SGL entry contains zero data"},
1401da177e4SLinus Torvalds 	{0x0101, "Invalid command opcode"},
1411da177e4SLinus Torvalds 	{0x0102, "SGL entry has unaligned address"},
1421da177e4SLinus Torvalds 	{0x0103, "SGL size does not match command"},
1431da177e4SLinus Torvalds 	{0x0104, "SGL entry has illegal length"},
1441da177e4SLinus Torvalds 	{0x0105, "Command packet is not aligned"},
1451da177e4SLinus Torvalds 	{0x0106, "Invalid request ID"},
1461da177e4SLinus Torvalds 	{0x0107, "Duplicate request ID"},
1471da177e4SLinus Torvalds 	{0x0108, "ID not locked"},
1481da177e4SLinus Torvalds 	{0x0109, "LBA out of range"},
1491da177e4SLinus Torvalds 	{0x010A, "Logical unit not supported"},
1501da177e4SLinus Torvalds 	{0x010B, "Parameter table does not exist"},
1511da177e4SLinus Torvalds 	{0x010C, "Parameter index does not exist"},
1521da177e4SLinus Torvalds 	{0x010D, "Invalid field in CDB"},
1531da177e4SLinus Torvalds 	{0x010E, "Specified port has invalid drive"},
1541da177e4SLinus Torvalds 	{0x010F, "Parameter item size mismatch"},
1551da177e4SLinus Torvalds 	{0x0110, "Failed memory allocation"},
1561da177e4SLinus Torvalds 	{0x0111, "Memory request too large"},
1571da177e4SLinus Torvalds 	{0x0112, "Out of memory segments"},
1581da177e4SLinus Torvalds 	{0x0113, "Invalid address to deallocate"},
1591da177e4SLinus Torvalds 	{0x0114, "Out of memory"},
1601da177e4SLinus Torvalds 	{0x0115, "Out of heap"},
1611da177e4SLinus Torvalds 	{0x0120, "Double degrade"},
1621da177e4SLinus Torvalds 	{0x0121, "Drive not degraded"},
1631da177e4SLinus Torvalds 	{0x0122, "Reconstruct error"},
1641da177e4SLinus Torvalds 	{0x0123, "Replace not accepted"},
1651da177e4SLinus Torvalds 	{0x0124, "Replace drive capacity too small"},
1661da177e4SLinus Torvalds 	{0x0125, "Sector count not allowed"},
1671da177e4SLinus Torvalds 	{0x0126, "No spares left"},
1681da177e4SLinus Torvalds 	{0x0127, "Reconstruct error"},
1691da177e4SLinus Torvalds 	{0x0128, "Unit is offline"},
1701da177e4SLinus Torvalds 	{0x0129, "Cannot update status to DCB"},
1711da177e4SLinus Torvalds 	{0x0130, "Invalid stripe handle"},
1721da177e4SLinus Torvalds 	{0x0131, "Handle that was not locked"},
1731da177e4SLinus Torvalds 	{0x0132, "Handle that was not empty"},
1741da177e4SLinus Torvalds 	{0x0133, "Handle has different owner"},
1751da177e4SLinus Torvalds 	{0x0140, "IPR has parent"},
1761da177e4SLinus Torvalds 	{0x0150, "Illegal Pbuf address alignment"},
1771da177e4SLinus Torvalds 	{0x0151, "Illegal Pbuf transfer length"},
1781da177e4SLinus Torvalds 	{0x0152, "Illegal Sbuf address alignment"},
1791da177e4SLinus Torvalds 	{0x0153, "Illegal Sbuf transfer length"},
1801da177e4SLinus Torvalds 	{0x0160, "Command packet too large"},
1811da177e4SLinus Torvalds 	{0x0161, "SGL exceeds maximum length"},
1821da177e4SLinus Torvalds 	{0x0162, "SGL has too many entries"},
1831da177e4SLinus Torvalds 	{0x0170, "Insufficient resources for rebuilder"},
1841da177e4SLinus Torvalds 	{0x0171, "Verify error (data != parity)"},
1851da177e4SLinus Torvalds 	{0x0180, "Requested segment not in directory of this DCB"},
1861da177e4SLinus Torvalds 	{0x0181, "DCB segment has unsupported version"},
1871da177e4SLinus Torvalds 	{0x0182, "DCB segment has checksum error"},
1881da177e4SLinus Torvalds 	{0x0183, "DCB support (settings) segment invalid"},
1891da177e4SLinus Torvalds 	{0x0184, "DCB UDB (unit descriptor block) segment invalid"},
1901da177e4SLinus Torvalds 	{0x0185, "DCB GUID (globally unique identifier) segment invalid"},
1911da177e4SLinus Torvalds 	{0x01A0, "Could not clear Sbuf"},
1921da177e4SLinus Torvalds 	{0x01C0, "Flash identify failed"},
1931da177e4SLinus Torvalds 	{0x01C1, "Flash out of bounds"},
1941da177e4SLinus Torvalds 	{0x01C2, "Flash verify error"},
1951da177e4SLinus Torvalds 	{0x01C3, "Flash file object not found"},
1961da177e4SLinus Torvalds 	{0x01C4, "Flash file already present"},
1971da177e4SLinus Torvalds 	{0x01C5, "Flash file system full"},
1981da177e4SLinus Torvalds 	{0x01C6, "Flash file not present"},
1991da177e4SLinus Torvalds 	{0x01C7, "Flash file size error"},
2001da177e4SLinus Torvalds 	{0x01C8, "Bad flash file checksum"},
2011da177e4SLinus Torvalds 	{0x01CA, "Corrupt flash file system detected"},
2021da177e4SLinus Torvalds 	{0x01D0, "Invalid field in parameter list"},
2031da177e4SLinus Torvalds 	{0x01D1, "Parameter list length error"},
2041da177e4SLinus Torvalds 	{0x01D2, "Parameter item is not changeable"},
2051da177e4SLinus Torvalds 	{0x01D3, "Parameter item is not saveable"},
2061da177e4SLinus Torvalds 	{0x0200, "UDMA CRC error"},
2071da177e4SLinus Torvalds 	{0x0201, "Internal CRC error"},
2081da177e4SLinus Torvalds 	{0x0202, "Data ECC error"},
2091da177e4SLinus Torvalds 	{0x0203, "ADP level 1 error"},
2101da177e4SLinus Torvalds 	{0x0204, "Port timeout"},
2111da177e4SLinus Torvalds 	{0x0205, "Drive power on reset"},
2121da177e4SLinus Torvalds 	{0x0206, "ADP level 2 error"},
2131da177e4SLinus Torvalds 	{0x0207, "Soft reset failed"},
2141da177e4SLinus Torvalds 	{0x0208, "Drive not ready"},
2151da177e4SLinus Torvalds 	{0x0209, "Unclassified port error"},
2161da177e4SLinus Torvalds 	{0x020A, "Drive aborted command"},
2171da177e4SLinus Torvalds 	{0x0210, "Internal CRC error"},
2181da177e4SLinus Torvalds 	{0x0211, "PCI abort error"},
2191da177e4SLinus Torvalds 	{0x0212, "PCI parity error"},
2201da177e4SLinus Torvalds 	{0x0213, "Port handler error"},
2211da177e4SLinus Torvalds 	{0x0214, "Token interrupt count error"},
2221da177e4SLinus Torvalds 	{0x0215, "Timeout waiting for PCI transfer"},
2231da177e4SLinus Torvalds 	{0x0216, "Corrected buffer ECC"},
2241da177e4SLinus Torvalds 	{0x0217, "Uncorrected buffer ECC"},
2251da177e4SLinus Torvalds 	{0x0230, "Unsupported command during flash recovery"},
2261da177e4SLinus Torvalds 	{0x0231, "Next image buffer expected"},
2271da177e4SLinus Torvalds 	{0x0232, "Binary image architecture incompatible"},
2281da177e4SLinus Torvalds 	{0x0233, "Binary image has no signature"},
2291da177e4SLinus Torvalds 	{0x0234, "Binary image has bad checksum"},
2301da177e4SLinus Torvalds 	{0x0235, "Image downloaded overflowed buffer"},
2311da177e4SLinus Torvalds 	{0x0240, "I2C device not found"},
2321da177e4SLinus Torvalds 	{0x0241, "I2C transaction aborted"},
2331da177e4SLinus Torvalds 	{0x0242, "SO-DIMM parameter(s) incompatible using defaults"},
2341da177e4SLinus Torvalds 	{0x0243, "SO-DIMM unsupported"},
2351da177e4SLinus Torvalds 	{0x0248, "SPI transfer status error"},
2361da177e4SLinus Torvalds 	{0x0249, "SPI transfer timeout error"},
2371da177e4SLinus Torvalds 	{0x0250, "Invalid unit descriptor size in CreateUnit"},
2381da177e4SLinus Torvalds 	{0x0251, "Unit descriptor size exceeds data buffer in CreateUnit"},
2391da177e4SLinus Torvalds 	{0x0252, "Invalid value in CreateUnit descriptor"},
2401da177e4SLinus Torvalds 	{0x0253, "Inadequate disk space to support descriptor in CreateUnit"},
2411da177e4SLinus Torvalds 	{0x0254, "Unable to create data channel for this unit descriptor"},
2421da177e4SLinus Torvalds 	{0x0255, "CreateUnit descriptor specifies a drive already in use"},
2431da177e4SLinus Torvalds 	{0x0256, "Unable to write configuration to all disks during CreateUnit"},
2441da177e4SLinus Torvalds 	{0x0257, "CreateUnit does not support this descriptor version"},
2451da177e4SLinus Torvalds 	{0x0258, "Invalid subunit for RAID 0 or 5 in CreateUnit"},
2461da177e4SLinus Torvalds 	{0x0259, "Too many descriptors in CreateUnit"},
2471da177e4SLinus Torvalds 	{0x025A, "Invalid configuration specified in CreateUnit descriptor"},
2481da177e4SLinus Torvalds 	{0x025B, "Invalid LBA offset specified in CreateUnit descriptor"},
2491da177e4SLinus Torvalds 	{0x025C, "Invalid stripelet size specified in CreateUnit descriptor"},
2501da177e4SLinus Torvalds 	{0x0260, "SMART attribute exceeded threshold"},
2511da177e4SLinus Torvalds 	{0xFFFFFFFF, (char*) 0}
2521da177e4SLinus Torvalds };
2531da177e4SLinus Torvalds 
2541da177e4SLinus Torvalds /* Control register bit definitions */
2551da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_HOST_INTERRUPT	       0x00080000
2561da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT   0x00040000
2571da177e4SLinus Torvalds #define TW_CONTROL_MASK_COMMAND_INTERRUPT      0x00020000
2581da177e4SLinus Torvalds #define TW_CONTROL_MASK_RESPONSE_INTERRUPT     0x00010000
2591da177e4SLinus Torvalds #define TW_CONTROL_UNMASK_COMMAND_INTERRUPT    0x00008000
2601da177e4SLinus Torvalds #define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT   0x00004000
2611da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_ERROR_STATUS	       0x00000200
2621da177e4SLinus Torvalds #define TW_CONTROL_ISSUE_SOFT_RESET	       0x00000100
2631da177e4SLinus Torvalds #define TW_CONTROL_ENABLE_INTERRUPTS	       0x00000080
2641da177e4SLinus Torvalds #define TW_CONTROL_DISABLE_INTERRUPTS	       0x00000040
2651da177e4SLinus Torvalds #define TW_CONTROL_ISSUE_HOST_INTERRUPT	       0x00000020
2661da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_PARITY_ERROR	       0x00800000
2671da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_QUEUE_ERROR	       0x00400000
2681da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_PCI_ABORT	       0x00100000
2691da177e4SLinus Torvalds 
2701da177e4SLinus Torvalds /* Status register bit definitions */
2711da177e4SLinus Torvalds #define TW_STATUS_MAJOR_VERSION_MASK	       0xF0000000
2721da177e4SLinus Torvalds #define TW_STATUS_MINOR_VERSION_MASK	       0x0F000000
2731da177e4SLinus Torvalds #define TW_STATUS_PCI_PARITY_ERROR	       0x00800000
2741da177e4SLinus Torvalds #define TW_STATUS_QUEUE_ERROR		       0x00400000
2751da177e4SLinus Torvalds #define TW_STATUS_MICROCONTROLLER_ERROR	       0x00200000
2761da177e4SLinus Torvalds #define TW_STATUS_PCI_ABORT		       0x00100000
2771da177e4SLinus Torvalds #define TW_STATUS_HOST_INTERRUPT	       0x00080000
2781da177e4SLinus Torvalds #define TW_STATUS_ATTENTION_INTERRUPT	       0x00040000
2791da177e4SLinus Torvalds #define TW_STATUS_COMMAND_INTERRUPT	       0x00020000
2801da177e4SLinus Torvalds #define TW_STATUS_RESPONSE_INTERRUPT	       0x00010000
2811da177e4SLinus Torvalds #define TW_STATUS_COMMAND_QUEUE_FULL	       0x00008000
2821da177e4SLinus Torvalds #define TW_STATUS_RESPONSE_QUEUE_EMPTY	       0x00004000
2831da177e4SLinus Torvalds #define TW_STATUS_MICROCONTROLLER_READY	       0x00002000
2841da177e4SLinus Torvalds #define TW_STATUS_COMMAND_QUEUE_EMPTY	       0x00001000
2851da177e4SLinus Torvalds #define TW_STATUS_EXPECTED_BITS		       0x00002000
28649bfd8dbSadam radford #define TW_STATUS_UNEXPECTED_BITS	       0x00F00000
28749bfd8dbSadam radford #define TW_STATUS_VALID_INTERRUPT	       0x00DF0000
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds /* PCI related defines */
2901da177e4SLinus Torvalds #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
2911da177e4SLinus Torvalds #define TW_PCI_CLEAR_PCI_ABORT     0x2000
2921da177e4SLinus Torvalds 
2931da177e4SLinus Torvalds /* Command packet opcodes used by the driver */
2941da177e4SLinus Torvalds #define TW_OP_INIT_CONNECTION	0x1
2951da177e4SLinus Torvalds #define TW_OP_GET_PARAM		0x12
2961da177e4SLinus Torvalds #define TW_OP_SET_PARAM		0x13
2971da177e4SLinus Torvalds #define TW_OP_EXECUTE_SCSI	0x10
2981da177e4SLinus Torvalds #define TW_OP_DOWNLOAD_FIRMWARE 0x16
2991da177e4SLinus Torvalds #define TW_OP_RESET		0x1C
3001da177e4SLinus Torvalds 
3011da177e4SLinus Torvalds /* Asynchronous Event Notification (AEN) codes used by the driver */
3021da177e4SLinus Torvalds #define TW_AEN_QUEUE_EMPTY	0x0000
3031da177e4SLinus Torvalds #define TW_AEN_SOFT_RESET	0x0001
3041da177e4SLinus Torvalds #define TW_AEN_SYNC_TIME_WITH_HOST 0x031
3051da177e4SLinus Torvalds #define TW_AEN_SEVERITY_ERROR	0x1
3061da177e4SLinus Torvalds #define TW_AEN_SEVERITY_DEBUG    0x4
3071da177e4SLinus Torvalds #define TW_AEN_NOT_RETRIEVED 0x1
3081da177e4SLinus Torvalds #define TW_AEN_RETRIEVED 0x2
3091da177e4SLinus Torvalds 
3101da177e4SLinus Torvalds /* Command state defines */
3111da177e4SLinus Torvalds #define TW_S_INITIAL   0x1  /* Initial state */
3121da177e4SLinus Torvalds #define TW_S_STARTED   0x2  /* Id in use */
3131da177e4SLinus Torvalds #define TW_S_POSTED    0x4  /* Posted to the controller */
3141da177e4SLinus Torvalds #define TW_S_PENDING   0x8  /* Waiting to be posted in isr */
3151da177e4SLinus Torvalds #define TW_S_COMPLETED 0x10 /* Completed by isr */
3161da177e4SLinus Torvalds #define TW_S_FINISHED  0x20 /* I/O completely done */
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds /* Compatibility defines */
3191da177e4SLinus Torvalds #define TW_9000_ARCH_ID 0x5
3203dabec71Sadam radford #define TW_CURRENT_DRIVER_SRL 35
3213dabec71Sadam radford #define TW_CURRENT_DRIVER_BUILD 0
32249bfd8dbSadam radford #define TW_CURRENT_DRIVER_BRANCH 0
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds /* Misc defines */
32549bfd8dbSadam radford #define TW_9550SX_DRAIN_COMPLETED	      0xFFFF
3261da177e4SLinus Torvalds #define TW_SECTOR_SIZE			      512
3271da177e4SLinus Torvalds #define TW_ALIGNMENT_9000		      4  /* 4 bytes */
3281da177e4SLinus Torvalds #define TW_ALIGNMENT_9000_SGL		      0x3
3291da177e4SLinus Torvalds #define TW_MAX_UNITS			      16
3304039c30eSadam radford #define TW_MAX_UNITS_9650SE		      32
3311da177e4SLinus Torvalds #define TW_INIT_MESSAGE_CREDITS		      0x100
3321da177e4SLinus Torvalds #define TW_INIT_COMMAND_PACKET_SIZE	      0x3
3331da177e4SLinus Torvalds #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
3341da177e4SLinus Torvalds #define TW_EXTENDED_INIT_CONNECT	      0x2
3351da177e4SLinus Torvalds #define TW_BUNDLED_FW_SAFE_TO_FLASH	      0x4
3361da177e4SLinus Torvalds #define TW_CTLR_FW_RECOMMENDS_FLASH	      0x8
3371da177e4SLinus Torvalds #define TW_CTLR_FW_COMPATIBLE		      0x2
3381da177e4SLinus Torvalds #define TW_BASE_FW_SRL			      24
3391da177e4SLinus Torvalds #define TW_BASE_FW_BRANCH		      0
3401da177e4SLinus Torvalds #define TW_BASE_FW_BUILD		      1
3411da177e4SLinus Torvalds #define TW_FW_SRL_LUNS_SUPPORTED	      28
3421da177e4SLinus Torvalds #define TW_Q_LENGTH			      256
3431da177e4SLinus Torvalds #define TW_Q_START			      0
3441da177e4SLinus Torvalds #define TW_MAX_SLOT			      32
3451da177e4SLinus Torvalds #define TW_MAX_RESET_TRIES		      2
3461da177e4SLinus Torvalds #define TW_MAX_CMDS_PER_LUN		      254
3471da177e4SLinus Torvalds #define TW_MAX_RESPONSE_DRAIN		      256
3483dabec71Sadam radford #define TW_MAX_AEN_DRAIN		      255
3491da177e4SLinus Torvalds #define TW_IN_RESET			      2
3503dabec71Sadam radford #define TW_USING_MSI			      3
3511da177e4SLinus Torvalds #define TW_IN_ATTENTION_LOOP		      4
3521da177e4SLinus Torvalds #define TW_MAX_SECTORS			      256
3531da177e4SLinus Torvalds #define TW_AEN_WAIT_TIME		      1000
3541da177e4SLinus Torvalds #define TW_IOCTL_WAIT_TIME		      (1 * HZ) /* 1 second */
3551da177e4SLinus Torvalds #define TW_MAX_CDB_LEN			      16
3561da177e4SLinus Torvalds #define TW_ISR_DONT_COMPLETE		      2
3571da177e4SLinus Torvalds #define TW_ISR_DONT_RESULT		      3
3581da177e4SLinus Torvalds #define TW_IOCTL_CHRDEV_TIMEOUT		      60 /* 60 seconds */
3591da177e4SLinus Torvalds #define TW_IOCTL_CHRDEV_FREE		      -1
3601da177e4SLinus Torvalds #define TW_COMMAND_OFFSET		      128 /* 128 bytes */
3611da177e4SLinus Torvalds #define TW_VERSION_TABLE		      0x0402
3621da177e4SLinus Torvalds #define TW_TIMEKEEP_TABLE		      0x040A
3631da177e4SLinus Torvalds #define TW_INFORMATION_TABLE		      0x0403
3641da177e4SLinus Torvalds #define TW_PARAM_FWVER			      3
3651da177e4SLinus Torvalds #define TW_PARAM_FWVER_LENGTH		      16
3661da177e4SLinus Torvalds #define TW_PARAM_BIOSVER		      4
3671da177e4SLinus Torvalds #define TW_PARAM_BIOSVER_LENGTH		      16
3681da177e4SLinus Torvalds #define TW_PARAM_PORTCOUNT		      3
3691da177e4SLinus Torvalds #define TW_PARAM_PORTCOUNT_LENGTH	      1
3701da177e4SLinus Torvalds #define TW_MIN_SGL_LENGTH		      0x200 /* 512 bytes */
3711da177e4SLinus Torvalds #define TW_MAX_SENSE_LENGTH		      256
3721da177e4SLinus Torvalds #define TW_EVENT_SOURCE_AEN		      0x1000
3731da177e4SLinus Torvalds #define TW_EVENT_SOURCE_COMMAND		      0x1001
3741da177e4SLinus Torvalds #define TW_EVENT_SOURCE_PCHIP		      0x1002
3751da177e4SLinus Torvalds #define TW_EVENT_SOURCE_DRIVER		      0x1003
3761da177e4SLinus Torvalds #define TW_IOCTL_GET_COMPATIBILITY_INFO	      0x101
3771da177e4SLinus Torvalds #define TW_IOCTL_GET_LAST_EVENT		      0x102
3781da177e4SLinus Torvalds #define TW_IOCTL_GET_FIRST_EVENT	      0x103
3791da177e4SLinus Torvalds #define TW_IOCTL_GET_NEXT_EVENT		      0x104
3801da177e4SLinus Torvalds #define TW_IOCTL_GET_PREVIOUS_EVENT	      0x105
3811da177e4SLinus Torvalds #define TW_IOCTL_GET_LOCK		      0x106
3821da177e4SLinus Torvalds #define TW_IOCTL_RELEASE_LOCK		      0x107
3831da177e4SLinus Torvalds #define TW_IOCTL_FIRMWARE_PASS_THROUGH	      0x108
3841da177e4SLinus Torvalds #define TW_IOCTL_ERROR_STATUS_NOT_LOCKED      0x1001 // Not locked
3851da177e4SLinus Torvalds #define TW_IOCTL_ERROR_STATUS_LOCKED	      0x1002 // Already locked
3861da177e4SLinus Torvalds #define TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS  0x1003 // No more events
3871da177e4SLinus Torvalds #define TW_IOCTL_ERROR_STATUS_AEN_CLOBBER     0x1004 // AEN clobber occurred
3881da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_EFAULT	      -EFAULT // Bad address
3891da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_EINTR		      -EINTR  // Interrupted system call
3901da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_EINVAL	      -EINVAL // Invalid argument
3911da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_ENOMEM	      -ENOMEM // Out of memory
3921da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_ERESTARTSYS	      -ERESTARTSYS // Restart system call
3931da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_EIO		      -EIO // I/O error
3941da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_ENOTTY	      -ENOTTY // Not a typewriter
3951da177e4SLinus Torvalds #define TW_IOCTL_ERROR_OS_ENODEV	      -ENODEV // No such device
3961da177e4SLinus Torvalds #define TW_ALLOCATION_LENGTH		      128
3971da177e4SLinus Torvalds #define TW_SENSE_DATA_LENGTH		      18
3981da177e4SLinus Torvalds #define TW_STATUS_CHECK_CONDITION	      2
3991da177e4SLinus Torvalds #define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
4001da177e4SLinus Torvalds #define TW_ERROR_UNIT_OFFLINE		      0x128
4011da177e4SLinus Torvalds #define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
4021da177e4SLinus Torvalds #define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
4031da177e4SLinus Torvalds #define TW_MESSAGE_SOURCE_LINUX_DRIVER	      6
4041da177e4SLinus Torvalds #define TW_DRIVER TW_MESSAGE_SOURCE_LINUX_DRIVER
4051da177e4SLinus Torvalds #define TW_MESSAGE_SOURCE_LINUX_OS	      9
4061da177e4SLinus Torvalds #define TW_OS TW_MESSAGE_SOURCE_LINUX_OS
4071da177e4SLinus Torvalds #ifndef PCI_DEVICE_ID_3WARE_9000
4081da177e4SLinus Torvalds #define PCI_DEVICE_ID_3WARE_9000 0x1002
4091da177e4SLinus Torvalds #endif
41049bfd8dbSadam radford #ifndef PCI_DEVICE_ID_3WARE_9550SX
41149bfd8dbSadam radford #define PCI_DEVICE_ID_3WARE_9550SX 0x1003
41249bfd8dbSadam radford #endif
4134039c30eSadam radford #ifndef PCI_DEVICE_ID_3WARE_9650SE
4144039c30eSadam radford #define PCI_DEVICE_ID_3WARE_9650SE 0x1004
4154039c30eSadam radford #endif
4160e78d158Sadam radford #ifndef PCI_DEVICE_ID_3WARE_9690SA
4170e78d158Sadam radford #define PCI_DEVICE_ID_3WARE_9690SA 0x1005
4180e78d158Sadam radford #endif
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds /* Bitmask macros to eliminate bitfields */
4211da177e4SLinus Torvalds 
4221da177e4SLinus Torvalds /* opcode: 5, reserved: 3 */
4231da177e4SLinus Torvalds #define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
4241da177e4SLinus Torvalds #define TW_OP_OUT(x) (x & 0x1f)
4251da177e4SLinus Torvalds 
4261da177e4SLinus Torvalds /* opcode: 5, sgloffset: 3 */
4271da177e4SLinus Torvalds #define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
4281da177e4SLinus Torvalds #define TW_SGL_OUT(x) ((x >> 5) & 0x7)
4291da177e4SLinus Torvalds 
4301da177e4SLinus Torvalds /* severity: 3, reserved: 5 */
4311da177e4SLinus Torvalds #define TW_SEV_OUT(x) (x & 0x7)
4321da177e4SLinus Torvalds 
4331da177e4SLinus Torvalds /* reserved_1: 4, response_id: 8, reserved_2: 20 */
4341da177e4SLinus Torvalds #define TW_RESID_OUT(x) ((x >> 4) & 0xff)
4351da177e4SLinus Torvalds 
4361da177e4SLinus Torvalds /* request_id: 12, lun: 4 */
437bf4eebbfSHannes Reinecke #define TW_REQ_LUN_IN(lun, request_id)			\
438*05f7f1b9SSamuel Holland 	cpu_to_le16(((lun << 12) & 0xf000) | (request_id & 0xfff))
439*05f7f1b9SSamuel Holland #define TW_LUN_OUT(lun) ((le16_to_cpu(lun) >> 12) & 0xf)
4401da177e4SLinus Torvalds 
4411da177e4SLinus Torvalds /* Macros */
4421da177e4SLinus Torvalds #define TW_CONTROL_REG_ADDR(x) (x->base_addr)
4431da177e4SLinus Torvalds #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
444bf4eebbfSHannes Reinecke #define TW_COMMAND_QUEUE_REG_ADDR(x) \
445bf4eebbfSHannes Reinecke 	(sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
446bf4eebbfSHannes Reinecke #define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) \
447bf4eebbfSHannes Reinecke 	((unsigned char __iomem *)x->base_addr + 0x20)
448bf4eebbfSHannes Reinecke #define TW_RESPONSE_QUEUE_REG_ADDR(x) \
449bf4eebbfSHannes Reinecke 	((unsigned char __iomem *)x->base_addr + 0xC)
450bf4eebbfSHannes Reinecke #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) \
451bf4eebbfSHannes Reinecke 	((unsigned char __iomem *)x->base_addr + 0x30)
452bf4eebbfSHannes Reinecke #define TW_CLEAR_ALL_INTERRUPTS(x) \
453bf4eebbfSHannes Reinecke 	(writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
454bf4eebbfSHannes Reinecke #define TW_CLEAR_ATTENTION_INTERRUPT(x) \
455bf4eebbfSHannes Reinecke 	(writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
456bf4eebbfSHannes Reinecke #define TW_CLEAR_HOST_INTERRUPT(x) \
457bf4eebbfSHannes Reinecke 	(writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
458bf4eebbfSHannes Reinecke #define TW_DISABLE_INTERRUPTS(x) \
459bf4eebbfSHannes Reinecke 	(writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
460bf4eebbfSHannes Reinecke #define TW_ENABLE_AND_CLEAR_INTERRUPTS(x)				\
461bf4eebbfSHannes Reinecke 	(writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |			\
462bf4eebbfSHannes Reinecke 		TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |			\
463bf4eebbfSHannes Reinecke 		TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
464bf4eebbfSHannes Reinecke #define TW_MASK_COMMAND_INTERRUPT(x)					\
465bf4eebbfSHannes Reinecke 	(writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
466bf4eebbfSHannes Reinecke #define TW_UNMASK_COMMAND_INTERRUPT(x)					\
467bf4eebbfSHannes Reinecke 	(writel(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
4681da177e4SLinus Torvalds #define TW_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET |	\
4691da177e4SLinus Torvalds 			TW_CONTROL_CLEAR_HOST_INTERRUPT | \
4701da177e4SLinus Torvalds 			TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
4711da177e4SLinus Torvalds 			TW_CONTROL_MASK_COMMAND_INTERRUPT | \
4721da177e4SLinus Torvalds 			TW_CONTROL_MASK_RESPONSE_INTERRUPT | \
4731da177e4SLinus Torvalds 			TW_CONTROL_CLEAR_ERROR_STATUS | \
4741da177e4SLinus Torvalds 			TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
4751da177e4SLinus Torvalds #define TW_PRINTK(h,a,b,c) { \
4761da177e4SLinus Torvalds if (h) \
4771da177e4SLinus Torvalds printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
4781da177e4SLinus Torvalds else \
4791da177e4SLinus Torvalds printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
4801da177e4SLinus Torvalds }
4811da177e4SLinus Torvalds #define TW_MAX_LUNS(srl) (srl < TW_FW_SRL_LUNS_SUPPORTED ? 1 : 16)
4821da177e4SLinus Torvalds #define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 5 : 4)
4831da177e4SLinus Torvalds #define TW_APACHE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 72 : 109)
4841da177e4SLinus Torvalds #define TW_ESCALADE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 41 : 62)
4851da177e4SLinus Torvalds #define TW_PADDING_LENGTH (sizeof(dma_addr_t) > 4 ? 8 : 0)
4861da177e4SLinus Torvalds 
487d133b441SSamuel Holland #if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)
488*05f7f1b9SSamuel Holland typedef __le64 twa_addr_t;
489*05f7f1b9SSamuel Holland #define TW_CPU_TO_SGL(x) cpu_to_le64(x)
490d133b441SSamuel Holland #else
491*05f7f1b9SSamuel Holland typedef __le32 twa_addr_t;
492*05f7f1b9SSamuel Holland #define TW_CPU_TO_SGL(x) cpu_to_le32(x)
493d133b441SSamuel Holland #endif
4941da177e4SLinus Torvalds 
4951da177e4SLinus Torvalds /* Scatter Gather List Entry */
4961da177e4SLinus Torvalds typedef struct TAG_TW_SG_Entry {
497d133b441SSamuel Holland 	twa_addr_t	address;
498*05f7f1b9SSamuel Holland 	__le32		length;
499d133b441SSamuel Holland } __packed TW_SG_Entry;
5001da177e4SLinus Torvalds 
5011da177e4SLinus Torvalds /* Command Packet */
5021da177e4SLinus Torvalds typedef struct TW_Command {
503*05f7f1b9SSamuel Holland 	u8	opcode__sgloffset;
504*05f7f1b9SSamuel Holland 	u8	size;
505*05f7f1b9SSamuel Holland 	u8	request_id;
506*05f7f1b9SSamuel Holland 	u8	unit__hostid;
5071da177e4SLinus Torvalds 	/* Second DWORD */
508*05f7f1b9SSamuel Holland 	u8	status;
509*05f7f1b9SSamuel Holland 	u8	flags;
5101da177e4SLinus Torvalds 	union {
511*05f7f1b9SSamuel Holland 		__le16	block_count;
512*05f7f1b9SSamuel Holland 		__le16	parameter_count;
5131da177e4SLinus Torvalds 	} byte6_offset;
5141da177e4SLinus Torvalds 	union {
5151da177e4SLinus Torvalds 		struct {
516*05f7f1b9SSamuel Holland 			__le32		lba;
5171da177e4SLinus Torvalds 			TW_SG_Entry	sgl[TW_ESCALADE_MAX_SGL_LENGTH];
518d133b441SSamuel Holland 			twa_addr_t	padding;
5191da177e4SLinus Torvalds 		} io;
5201da177e4SLinus Torvalds 		struct {
5211da177e4SLinus Torvalds 			TW_SG_Entry	sgl[TW_ESCALADE_MAX_SGL_LENGTH];
522*05f7f1b9SSamuel Holland 			__le32		padding;
523d133b441SSamuel Holland 			twa_addr_t	padding2;
5241da177e4SLinus Torvalds 		} param;
5251da177e4SLinus Torvalds 	} byte8_offset;
5261da177e4SLinus Torvalds } TW_Command;
5271da177e4SLinus Torvalds 
5281da177e4SLinus Torvalds /* Command Packet for 9000+ controllers */
5291da177e4SLinus Torvalds typedef struct TAG_TW_Command_Apache {
530*05f7f1b9SSamuel Holland 	u8		opcode__reserved;
531*05f7f1b9SSamuel Holland 	u8		unit;
532*05f7f1b9SSamuel Holland 	__le16		request_id__lunl;
533*05f7f1b9SSamuel Holland 	u8		status;
534*05f7f1b9SSamuel Holland 	u8		sgl_offset;
535*05f7f1b9SSamuel Holland 	__le16		sgl_entries__lunh;
536*05f7f1b9SSamuel Holland 	u8		cdb[16];
5371da177e4SLinus Torvalds 	TW_SG_Entry	sg_list[TW_APACHE_MAX_SGL_LENGTH];
538*05f7f1b9SSamuel Holland 	u8		padding[TW_PADDING_LENGTH];
5391da177e4SLinus Torvalds } TW_Command_Apache;
5401da177e4SLinus Torvalds 
5411da177e4SLinus Torvalds /* New command packet header */
5421da177e4SLinus Torvalds typedef struct TAG_TW_Command_Apache_Header {
5431da177e4SLinus Torvalds 	unsigned char sense_data[TW_SENSE_DATA_LENGTH];
5441da177e4SLinus Torvalds 	struct {
545*05f7f1b9SSamuel Holland 		u8	reserved[4];
546*05f7f1b9SSamuel Holland 		__le16	error;
547*05f7f1b9SSamuel Holland 		u8	padding;
548*05f7f1b9SSamuel Holland 		u8	severity__reserved;
5491da177e4SLinus Torvalds 	} status_block;
5501da177e4SLinus Torvalds 	unsigned char err_specific_desc[98];
5511da177e4SLinus Torvalds 	struct {
552*05f7f1b9SSamuel Holland 		u8	size_header;
553*05f7f1b9SSamuel Holland 		u8	reserved[2];
554*05f7f1b9SSamuel Holland 		u8	size_sense;
5551da177e4SLinus Torvalds 	} header_desc;
5561da177e4SLinus Torvalds } TW_Command_Apache_Header;
5571da177e4SLinus Torvalds 
5581da177e4SLinus Torvalds /* This struct is a union of the 2 command packets */
5591da177e4SLinus Torvalds typedef struct TAG_TW_Command_Full {
5601da177e4SLinus Torvalds 	TW_Command_Apache_Header header;
5611da177e4SLinus Torvalds 	union {
5621da177e4SLinus Torvalds 		TW_Command oldcommand;
5631da177e4SLinus Torvalds 		TW_Command_Apache newcommand;
5641da177e4SLinus Torvalds 	} command;
5651da177e4SLinus Torvalds } TW_Command_Full;
5661da177e4SLinus Torvalds 
5671da177e4SLinus Torvalds /* Initconnection structure */
5681da177e4SLinus Torvalds typedef struct TAG_TW_Initconnect {
569*05f7f1b9SSamuel Holland 	u8	opcode__reserved;
570*05f7f1b9SSamuel Holland 	u8	size;
571*05f7f1b9SSamuel Holland 	u8	request_id;
572*05f7f1b9SSamuel Holland 	u8	res2;
573*05f7f1b9SSamuel Holland 	u8	status;
574*05f7f1b9SSamuel Holland 	u8	flags;
575*05f7f1b9SSamuel Holland 	__le16	message_credits;
576*05f7f1b9SSamuel Holland 	__le32	features;
577*05f7f1b9SSamuel Holland 	__le16	fw_srl;
578*05f7f1b9SSamuel Holland 	__le16	fw_arch_id;
579*05f7f1b9SSamuel Holland 	__le16	fw_branch;
580*05f7f1b9SSamuel Holland 	__le16	fw_build;
581*05f7f1b9SSamuel Holland 	__le32	result;
5821da177e4SLinus Torvalds } TW_Initconnect;
5831da177e4SLinus Torvalds 
5841da177e4SLinus Torvalds /* Event info structure */
5851da177e4SLinus Torvalds typedef struct TAG_TW_Event
5861da177e4SLinus Torvalds {
5871da177e4SLinus Torvalds 	unsigned int sequence_id;
5881da177e4SLinus Torvalds 	unsigned int time_stamp_sec;
5891da177e4SLinus Torvalds 	unsigned short aen_code;
5901da177e4SLinus Torvalds 	unsigned char severity;
5911da177e4SLinus Torvalds 	unsigned char retrieved;
5921da177e4SLinus Torvalds 	unsigned char repeat_count;
5931da177e4SLinus Torvalds 	unsigned char parameter_len;
5941da177e4SLinus Torvalds 	unsigned char parameter_data[98];
5951da177e4SLinus Torvalds } TW_Event;
5961da177e4SLinus Torvalds 
5971da177e4SLinus Torvalds typedef struct TAG_TW_Ioctl_Driver_Command {
5981da177e4SLinus Torvalds 	unsigned int control_code;
5991da177e4SLinus Torvalds 	unsigned int status;
6001da177e4SLinus Torvalds 	unsigned int unique_id;
6011da177e4SLinus Torvalds 	unsigned int sequence_id;
6021da177e4SLinus Torvalds 	unsigned int os_specific;
6031da177e4SLinus Torvalds 	unsigned int buffer_length;
6041da177e4SLinus Torvalds } TW_Ioctl_Driver_Command;
6051da177e4SLinus Torvalds 
6061da177e4SLinus Torvalds typedef struct TAG_TW_Ioctl_Apache {
6071da177e4SLinus Torvalds 	TW_Ioctl_Driver_Command driver_command;
6081da177e4SLinus Torvalds 	char padding[488];
6091da177e4SLinus Torvalds 	TW_Command_Full firmware_command;
61044c5027bSSamuel Holland 	char data_buffer[];
6111da177e4SLinus Torvalds } TW_Ioctl_Buf_Apache;
6121da177e4SLinus Torvalds 
6131da177e4SLinus Torvalds /* Lock structure for ioctl get/release lock */
6141da177e4SLinus Torvalds typedef struct TAG_TW_Lock {
6151da177e4SLinus Torvalds 	unsigned long timeout_msec;
6161da177e4SLinus Torvalds 	unsigned long time_remaining_msec;
6171da177e4SLinus Torvalds 	unsigned long force_flag;
6181da177e4SLinus Torvalds } TW_Lock;
6191da177e4SLinus Torvalds 
6201da177e4SLinus Torvalds /* GetParam descriptor */
6211da177e4SLinus Torvalds typedef struct {
622*05f7f1b9SSamuel Holland 	__le16	table_id;
623*05f7f1b9SSamuel Holland 	__le16	parameter_id;
624*05f7f1b9SSamuel Holland 	__le16	parameter_size_bytes;
625*05f7f1b9SSamuel Holland 	__le16  actual_parameter_size_bytes;
626*05f7f1b9SSamuel Holland 	u8	data[];
6271da177e4SLinus Torvalds } TW_Param_Apache, *PTW_Param_Apache;
6281da177e4SLinus Torvalds 
6291da177e4SLinus Torvalds /* Response queue */
6301da177e4SLinus Torvalds typedef union TAG_TW_Response_Queue {
6311da177e4SLinus Torvalds 	u32 response_id;
6321da177e4SLinus Torvalds 	u32 value;
6331da177e4SLinus Torvalds } TW_Response_Queue;
6341da177e4SLinus Torvalds 
6351da177e4SLinus Torvalds /* Compatibility information structure */
6361da177e4SLinus Torvalds typedef struct TAG_TW_Compatibility_Info
6371da177e4SLinus Torvalds {
6381da177e4SLinus Torvalds 	char driver_version[32];
6391da177e4SLinus Torvalds 	unsigned short working_srl;
6401da177e4SLinus Torvalds 	unsigned short working_branch;
6411da177e4SLinus Torvalds 	unsigned short working_build;
6421da177e4SLinus Torvalds 	unsigned short driver_srl_high;
6431da177e4SLinus Torvalds 	unsigned short driver_branch_high;
6441da177e4SLinus Torvalds 	unsigned short driver_build_high;
6451da177e4SLinus Torvalds 	unsigned short driver_srl_low;
6461da177e4SLinus Torvalds 	unsigned short driver_branch_low;
6471da177e4SLinus Torvalds 	unsigned short driver_build_low;
6484039c30eSadam radford 	unsigned short fw_on_ctlr_srl;
6494039c30eSadam radford 	unsigned short fw_on_ctlr_branch;
6504039c30eSadam radford 	unsigned short fw_on_ctlr_build;
6511da177e4SLinus Torvalds } TW_Compatibility_Info;
6521da177e4SLinus Torvalds 
6531da177e4SLinus Torvalds typedef struct TAG_TW_Device_Extension {
6541da177e4SLinus Torvalds 	u32			__iomem *base_addr;
6551da177e4SLinus Torvalds 	unsigned long		*generic_buffer_virt[TW_Q_LENGTH];
6561da177e4SLinus Torvalds 	dma_addr_t		generic_buffer_phys[TW_Q_LENGTH];
6571da177e4SLinus Torvalds 	TW_Command_Full		*command_packet_virt[TW_Q_LENGTH];
6581da177e4SLinus Torvalds 	dma_addr_t		command_packet_phys[TW_Q_LENGTH];
6591da177e4SLinus Torvalds 	struct pci_dev		*tw_pci_dev;
6601da177e4SLinus Torvalds 	struct scsi_cmnd	*srb[TW_Q_LENGTH];
6611da177e4SLinus Torvalds 	unsigned char		free_queue[TW_Q_LENGTH];
6621da177e4SLinus Torvalds 	unsigned char		free_head;
6631da177e4SLinus Torvalds 	unsigned char		free_tail;
6641da177e4SLinus Torvalds 	unsigned char		pending_queue[TW_Q_LENGTH];
6651da177e4SLinus Torvalds 	unsigned char		pending_head;
6661da177e4SLinus Torvalds 	unsigned char		pending_tail;
6671da177e4SLinus Torvalds 	int			state[TW_Q_LENGTH];
6681da177e4SLinus Torvalds 	unsigned int		posted_request_count;
6691da177e4SLinus Torvalds 	unsigned int		max_posted_request_count;
6701da177e4SLinus Torvalds 	unsigned int		pending_request_count;
6711da177e4SLinus Torvalds 	unsigned int		max_pending_request_count;
6721da177e4SLinus Torvalds 	unsigned int		max_sgl_entries;
6731da177e4SLinus Torvalds 	unsigned int		sgl_entries;
6741da177e4SLinus Torvalds 	unsigned int		num_resets;
6751da177e4SLinus Torvalds 	unsigned int		sector_count;
6761da177e4SLinus Torvalds 	unsigned int		max_sector_count;
6771da177e4SLinus Torvalds 	unsigned int		aen_count;
6781da177e4SLinus Torvalds 	struct Scsi_Host	*host;
6791da177e4SLinus Torvalds 	long			flags;
6801da177e4SLinus Torvalds 	int			reset_print;
6811da177e4SLinus Torvalds 	TW_Event		*event_queue[TW_Q_LENGTH];
6821da177e4SLinus Torvalds 	unsigned char		error_index;
6831da177e4SLinus Torvalds 	unsigned char		event_queue_wrapped;
6841da177e4SLinus Torvalds 	unsigned int		error_sequence_id;
6851da177e4SLinus Torvalds 	int			ioctl_sem_lock;
68607ffd4ceSArnd Bergmann 	ktime_t			ioctl_time;
6871da177e4SLinus Torvalds 	int			chrdev_request_id;
6881da177e4SLinus Torvalds 	wait_queue_head_t	ioctl_wqueue;
689a12e25bdSJes Sorensen 	struct mutex		ioctl_lock;
6901da177e4SLinus Torvalds 	char			aen_clobber;
6914039c30eSadam radford 	TW_Compatibility_Info	tw_compat_info;
6921da177e4SLinus Torvalds } TW_Device_Extension;
6931da177e4SLinus Torvalds 
6941da177e4SLinus Torvalds #endif /* _3W_9XXX_H */
6951da177e4SLinus Torvalds 
696