xref: /openbmc/linux/drivers/scsi/3w-xxxx.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds    3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
31da177e4SLinus Torvalds 
42c9bce5bSadam radford    Written By: Adam Radford <aradford@gmail.com>
51da177e4SLinus Torvalds    Modifications By: Joel Jacobson <linux@3ware.com>
61da177e4SLinus Torvalds                      Arnaldo Carvalho de Melo <acme@conectiva.com.br>
71da177e4SLinus Torvalds                      Brad Strand <linux@3ware.com>
81da177e4SLinus Torvalds 
94deedd84Sadam radford    Copyright (C) 1999-2010 3ware Inc.
101da177e4SLinus Torvalds 
1125985edcSLucas De Marchi    Kernel compatibility By:	Andre Hedrick <andre@suse.com>
121da177e4SLinus Torvalds    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds    This program is free software; you can redistribute it and/or modify
151da177e4SLinus Torvalds    it under the terms of the GNU General Public License as published by
161da177e4SLinus Torvalds    the Free Software Foundation; version 2 of the License.
171da177e4SLinus Torvalds 
181da177e4SLinus Torvalds    This program is distributed in the hope that it will be useful,
191da177e4SLinus Torvalds    but WITHOUT ANY WARRANTY; without even the implied warranty of
201da177e4SLinus Torvalds    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
211da177e4SLinus Torvalds    GNU General Public License for more details.
221da177e4SLinus Torvalds 
231da177e4SLinus Torvalds    NO WARRANTY
241da177e4SLinus Torvalds    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
251da177e4SLinus Torvalds    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
261da177e4SLinus Torvalds    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
271da177e4SLinus Torvalds    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
281da177e4SLinus Torvalds    solely responsible for determining the appropriateness of using and
291da177e4SLinus Torvalds    distributing the Program and assumes all risks associated with its
301da177e4SLinus Torvalds    exercise of rights under this Agreement, including but not limited to
311da177e4SLinus Torvalds    the risks and costs of program errors, damage to or loss of data,
321da177e4SLinus Torvalds    programs or equipment, and unavailability or interruption of operations.
331da177e4SLinus Torvalds 
341da177e4SLinus Torvalds    DISCLAIMER OF LIABILITY
351da177e4SLinus Torvalds    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
361da177e4SLinus Torvalds    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
371da177e4SLinus Torvalds    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
381da177e4SLinus Torvalds    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
391da177e4SLinus Torvalds    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
401da177e4SLinus Torvalds    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
411da177e4SLinus Torvalds    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds    You should have received a copy of the GNU General Public License
441da177e4SLinus Torvalds    along with this program; if not, write to the Free Software
451da177e4SLinus Torvalds    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds    Bugs/Comments/Suggestions should be mailed to:
482c9bce5bSadam radford 
492c9bce5bSadam radford    aradford@gmail.com
501da177e4SLinus Torvalds 
511da177e4SLinus Torvalds    For more information, goto:
524deedd84Sadam radford    http://www.lsi.com
531da177e4SLinus Torvalds */
541da177e4SLinus Torvalds 
551da177e4SLinus Torvalds #ifndef _3W_XXXX_H
561da177e4SLinus Torvalds #define _3W_XXXX_H
571da177e4SLinus Torvalds 
581da177e4SLinus Torvalds #include <linux/types.h>
591da177e4SLinus Torvalds 
601da177e4SLinus Torvalds /* AEN strings */
611da177e4SLinus Torvalds static char *tw_aen_string[] = {
621da177e4SLinus Torvalds 	[0x000] = "INFO: AEN queue empty",
631da177e4SLinus Torvalds 	[0x001] = "INFO: Soft reset occurred",
641da177e4SLinus Torvalds 	[0x002] = "ERROR: Unit degraded: Unit #",
651da177e4SLinus Torvalds 	[0x003] = "ERROR: Controller error",
661da177e4SLinus Torvalds 	[0x004] = "ERROR: Rebuild failed: Unit #",
671da177e4SLinus Torvalds 	[0x005] = "INFO: Rebuild complete: Unit #",
681da177e4SLinus Torvalds 	[0x006] = "ERROR: Incomplete unit detected: Unit #",
691da177e4SLinus Torvalds 	[0x007] = "INFO: Initialization complete: Unit #",
701da177e4SLinus Torvalds 	[0x008] = "WARNING: Unclean shutdown detected: Unit #",
711da177e4SLinus Torvalds 	[0x009] = "WARNING: ATA port timeout: Port #",
721da177e4SLinus Torvalds 	[0x00A] = "ERROR: Drive error: Port #",
731da177e4SLinus Torvalds 	[0x00B] = "INFO: Rebuild started: Unit #",
741da177e4SLinus Torvalds 	[0x00C] = "INFO: Initialization started: Unit #",
751da177e4SLinus Torvalds 	[0x00D] = "ERROR: Logical unit deleted: Unit #",
761da177e4SLinus Torvalds 	[0x00F] = "WARNING: SMART threshold exceeded: Port #",
771da177e4SLinus Torvalds 	[0x021] = "WARNING: ATA UDMA downgrade: Port #",
78d41ba22aSAlexey Dobriyan 	[0x022] = "WARNING: ATA UDMA upgrade: Port #",
791da177e4SLinus Torvalds 	[0x023] = "WARNING: Sector repair occurred: Port #",
801da177e4SLinus Torvalds 	[0x024] = "ERROR: SBUF integrity check failure",
811da177e4SLinus Torvalds 	[0x025] = "ERROR: Lost cached write: Port #",
821da177e4SLinus Torvalds 	[0x026] = "ERROR: Drive ECC error detected: Port #",
831da177e4SLinus Torvalds 	[0x027] = "ERROR: DCB checksum error: Port #",
841da177e4SLinus Torvalds 	[0x028] = "ERROR: DCB unsupported version: Port #",
851da177e4SLinus Torvalds 	[0x029] = "INFO: Verify started: Unit #",
861da177e4SLinus Torvalds 	[0x02A] = "ERROR: Verify failed: Port #",
871da177e4SLinus Torvalds 	[0x02B] = "INFO: Verify complete: Unit #",
881da177e4SLinus Torvalds 	[0x02C] = "WARNING: Overwrote bad sector during rebuild: Port #",
891da177e4SLinus Torvalds 	[0x02D] = "ERROR: Encountered bad sector during rebuild: Port #",
901da177e4SLinus Torvalds 	[0x02E] = "ERROR: Replacement drive is too small: Port #",
911da177e4SLinus Torvalds 	[0x02F] = "WARNING: Verify error: Unit not previously initialized: Unit #",
921da177e4SLinus Torvalds 	[0x030] = "ERROR: Drive not supported: Port #"
931da177e4SLinus Torvalds };
941da177e4SLinus Torvalds 
951da177e4SLinus Torvalds /*
961da177e4SLinus Torvalds    Sense key lookup table
971da177e4SLinus Torvalds    Format: ESDC/flags,SenseKey,AdditionalSenseCode,AdditionalSenseCodeQualifier
981da177e4SLinus Torvalds */
991da177e4SLinus Torvalds static unsigned char tw_sense_table[][4] =
1001da177e4SLinus Torvalds {
1011da177e4SLinus Torvalds   /* Codes for newer firmware */
1021da177e4SLinus Torvalds 	// ATA Error                    SCSI Error
1031da177e4SLinus Torvalds 	{0x01, 0x03, 0x13, 0x00}, // Address mark not found       Address mark not found for data field
1041da177e4SLinus Torvalds 	{0x04, 0x0b, 0x00, 0x00}, // Aborted command              Aborted command
1051da177e4SLinus Torvalds 	{0x10, 0x0b, 0x14, 0x00}, // ID not found                 Recorded entity not found
1061da177e4SLinus Torvalds 	{0x40, 0x03, 0x11, 0x00}, // Uncorrectable ECC error      Unrecovered read error
1071da177e4SLinus Torvalds 	{0x61, 0x04, 0x00, 0x00}, // Device fault                 Hardware error
1081da177e4SLinus Torvalds 	{0x84, 0x0b, 0x47, 0x00}, // Data CRC error               SCSI parity error
1091da177e4SLinus Torvalds 	{0xd0, 0x0b, 0x00, 0x00}, // Device busy                  Aborted command
1101da177e4SLinus Torvalds 	{0xd1, 0x0b, 0x00, 0x00}, // Device busy                  Aborted command
1111da177e4SLinus Torvalds 	{0x37, 0x02, 0x04, 0x00}, // Unit offline                 Not ready
1121da177e4SLinus Torvalds 	{0x09, 0x02, 0x04, 0x00}, // Unrecovered disk error       Not ready
1131da177e4SLinus Torvalds 
1141da177e4SLinus Torvalds 	/* Codes for older firmware */
1151da177e4SLinus Torvalds 	// 3ware Error                  SCSI Error
1161da177e4SLinus Torvalds 	{0x51, 0x0b, 0x00, 0x00}  // Unspecified                  Aborted command
1171da177e4SLinus Torvalds };
1181da177e4SLinus Torvalds 
1191da177e4SLinus Torvalds /* Control register bit definitions */
1201da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_HOST_INTERRUPT	       0x00080000
1211da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT   0x00040000
1221da177e4SLinus Torvalds #define TW_CONTROL_MASK_COMMAND_INTERRUPT      0x00020000
1231da177e4SLinus Torvalds #define TW_CONTROL_MASK_RESPONSE_INTERRUPT     0x00010000
1241da177e4SLinus Torvalds #define TW_CONTROL_UNMASK_COMMAND_INTERRUPT    0x00008000
1251da177e4SLinus Torvalds #define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT   0x00004000
1261da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_ERROR_STATUS	       0x00000200
1271da177e4SLinus Torvalds #define TW_CONTROL_ISSUE_SOFT_RESET	       0x00000100
1281da177e4SLinus Torvalds #define TW_CONTROL_ENABLE_INTERRUPTS	       0x00000080
1291da177e4SLinus Torvalds #define TW_CONTROL_DISABLE_INTERRUPTS	       0x00000040
1301da177e4SLinus Torvalds #define TW_CONTROL_ISSUE_HOST_INTERRUPT	       0x00000020
1311da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_PARITY_ERROR	       0x00800000
1321da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_QUEUE_ERROR	       0x00400000
1331da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_PCI_ABORT	       0x00100000
1341da177e4SLinus Torvalds #define TW_CONTROL_CLEAR_SBUF_WRITE_ERROR      0x00000008
1351da177e4SLinus Torvalds 
1361da177e4SLinus Torvalds /* Status register bit definitions */
1371da177e4SLinus Torvalds #define TW_STATUS_MAJOR_VERSION_MASK	       0xF0000000
1381da177e4SLinus Torvalds #define TW_STATUS_MINOR_VERSION_MASK	       0x0F000000
1391da177e4SLinus Torvalds #define TW_STATUS_PCI_PARITY_ERROR	       0x00800000
1401da177e4SLinus Torvalds #define TW_STATUS_QUEUE_ERROR		       0x00400000
1411da177e4SLinus Torvalds #define TW_STATUS_MICROCONTROLLER_ERROR	       0x00200000
1421da177e4SLinus Torvalds #define TW_STATUS_PCI_ABORT		       0x00100000
1431da177e4SLinus Torvalds #define TW_STATUS_HOST_INTERRUPT	       0x00080000
1441da177e4SLinus Torvalds #define TW_STATUS_ATTENTION_INTERRUPT	       0x00040000
1451da177e4SLinus Torvalds #define TW_STATUS_COMMAND_INTERRUPT	       0x00020000
1461da177e4SLinus Torvalds #define TW_STATUS_RESPONSE_INTERRUPT	       0x00010000
1471da177e4SLinus Torvalds #define TW_STATUS_COMMAND_QUEUE_FULL	       0x00008000
1481da177e4SLinus Torvalds #define TW_STATUS_RESPONSE_QUEUE_EMPTY	       0x00004000
1491da177e4SLinus Torvalds #define TW_STATUS_MICROCONTROLLER_READY	       0x00002000
1501da177e4SLinus Torvalds #define TW_STATUS_COMMAND_QUEUE_EMPTY	       0x00001000
1511da177e4SLinus Torvalds #define TW_STATUS_ALL_INTERRUPTS	       0x000F0000
1521da177e4SLinus Torvalds #define TW_STATUS_CLEARABLE_BITS	       0x00D00000
1531da177e4SLinus Torvalds #define TW_STATUS_EXPECTED_BITS		       0x00002000
1541da177e4SLinus Torvalds #define TW_STATUS_UNEXPECTED_BITS	       0x00F00008
1551da177e4SLinus Torvalds #define TW_STATUS_SBUF_WRITE_ERROR	       0x00000008
1561da177e4SLinus Torvalds #define TW_STATUS_VALID_INTERRUPT	       0x00DF0008
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds /* RESPONSE QUEUE BIT DEFINITIONS */
1591da177e4SLinus Torvalds #define TW_RESPONSE_ID_MASK		       0x00000FF0
1601da177e4SLinus Torvalds 
1611da177e4SLinus Torvalds /* PCI related defines */
1621da177e4SLinus Torvalds #define TW_IO_ADDRESS_RANGE		       0x10
1631da177e4SLinus Torvalds #define TW_DEVICE_NAME			       "3ware Storage Controller"
1641da177e4SLinus Torvalds #define TW_VENDOR_ID (0x13C1)	/* 3ware */
1651da177e4SLinus Torvalds #define TW_DEVICE_ID (0x1000)	/* Storage Controller */
1661da177e4SLinus Torvalds #define TW_DEVICE_ID2 (0x1001)  /* 7000 series controller */
1671da177e4SLinus Torvalds #define TW_NUMDEVICES 2
1681da177e4SLinus Torvalds #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
1691da177e4SLinus Torvalds #define TW_PCI_CLEAR_PCI_ABORT     0x2000
1701da177e4SLinus Torvalds 
1711da177e4SLinus Torvalds /* Command packet opcodes */
1721da177e4SLinus Torvalds #define TW_OP_NOP	      0x0
1731da177e4SLinus Torvalds #define TW_OP_INIT_CONNECTION 0x1
1741da177e4SLinus Torvalds #define TW_OP_READ	      0x2
1751da177e4SLinus Torvalds #define TW_OP_WRITE	      0x3
1761da177e4SLinus Torvalds #define TW_OP_VERIFY	      0x4
1771da177e4SLinus Torvalds #define TW_OP_GET_PARAM	      0x12
1781da177e4SLinus Torvalds #define TW_OP_SET_PARAM	      0x13
1791da177e4SLinus Torvalds #define TW_OP_SECTOR_INFO     0x1a
1801da177e4SLinus Torvalds #define TW_OP_AEN_LISTEN      0x1c
1811da177e4SLinus Torvalds #define TW_OP_FLUSH_CACHE     0x0e
1821da177e4SLinus Torvalds #define TW_CMD_PACKET	      0x1d
1831da177e4SLinus Torvalds #define TW_CMD_PACKET_WITH_DATA 0x1f
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds /* Asynchronous Event Notification (AEN) Codes */
1861da177e4SLinus Torvalds #define TW_AEN_QUEUE_EMPTY       0x0000
1871da177e4SLinus Torvalds #define TW_AEN_SOFT_RESET	 0x0001
1881da177e4SLinus Torvalds #define TW_AEN_DEGRADED_MIRROR   0x0002
1891da177e4SLinus Torvalds #define TW_AEN_CONTROLLER_ERROR  0x0003
1901da177e4SLinus Torvalds #define TW_AEN_REBUILD_FAIL      0x0004
1911da177e4SLinus Torvalds #define TW_AEN_REBUILD_DONE      0x0005
1921da177e4SLinus Torvalds #define TW_AEN_QUEUE_FULL	 0x00ff
1931da177e4SLinus Torvalds #define TW_AEN_TABLE_UNDEFINED   0x15
1941da177e4SLinus Torvalds #define TW_AEN_APORT_TIMEOUT     0x0009
1951da177e4SLinus Torvalds #define TW_AEN_DRIVE_ERROR       0x000A
1961da177e4SLinus Torvalds #define TW_AEN_SMART_FAIL	 0x000F
1971da177e4SLinus Torvalds #define TW_AEN_SBUF_FAIL	 0x0024
1981da177e4SLinus Torvalds 
1991da177e4SLinus Torvalds /* Misc defines */
2001da177e4SLinus Torvalds #define TW_ALIGNMENT_6000		      64 /* 64 bytes */
2011da177e4SLinus Torvalds #define TW_ALIGNMENT_7000		      4  /* 4 bytes */
2021da177e4SLinus Torvalds #define TW_MAX_UNITS			      16
2031da177e4SLinus Torvalds #define TW_COMMAND_ALIGNMENT_MASK	      0x1ff
2041da177e4SLinus Torvalds #define TW_INIT_MESSAGE_CREDITS		      0x100
2051da177e4SLinus Torvalds #define TW_INIT_COMMAND_PACKET_SIZE	      0x3
2061da177e4SLinus Torvalds #define TW_POLL_MAX_RETRIES		      20000
2071da177e4SLinus Torvalds #define TW_MAX_SGL_LENGTH		      62
2081da177e4SLinus Torvalds #define TW_ATA_PASS_SGL_MAX		      60
2091da177e4SLinus Torvalds #define TW_Q_LENGTH			      256
2101da177e4SLinus Torvalds #define TW_Q_START			      0
2111da177e4SLinus Torvalds #define TW_MAX_SLOT			      32
2121da177e4SLinus Torvalds #define TW_MAX_PCI_BUSES		      255
2131da177e4SLinus Torvalds #define TW_MAX_RESET_TRIES		      3
2141da177e4SLinus Torvalds #define TW_UNIT_INFORMATION_TABLE_BASE	      0x300
2151da177e4SLinus Torvalds #define TW_MAX_CMDS_PER_LUN		      254 /* 254 for io, 1 for
2161da177e4SLinus Torvalds                                                      chrdev ioctl, one for
2171da177e4SLinus Torvalds                                                      internal aen post */
2181da177e4SLinus Torvalds #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
2191da177e4SLinus Torvalds #define TW_IOCTL			      0x80
2201da177e4SLinus Torvalds #define TW_UNIT_ONLINE			      1
2211da177e4SLinus Torvalds #define TW_IN_INTR			      1
2221da177e4SLinus Torvalds #define TW_IN_RESET			      2
2231da177e4SLinus Torvalds #define TW_IN_CHRDEV_IOCTL		      3
2241da177e4SLinus Torvalds #define TW_MAX_SECTORS			      256
2251da177e4SLinus Torvalds #define TW_MAX_IOCTL_SECTORS		      512
2261da177e4SLinus Torvalds #define TW_AEN_WAIT_TIME		      1000
2271da177e4SLinus Torvalds #define TW_IOCTL_WAIT_TIME		      (1 * HZ) /* 1 second */
2281da177e4SLinus Torvalds #define TW_ISR_DONT_COMPLETE		      2
2291da177e4SLinus Torvalds #define TW_ISR_DONT_RESULT		      3
2301da177e4SLinus Torvalds #define TW_IOCTL_TIMEOUT		      25 /* 25 seconds */
2311da177e4SLinus Torvalds #define TW_IOCTL_CHRDEV_TIMEOUT		      60 /* 60 seconds */
2321da177e4SLinus Torvalds #define TW_IOCTL_CHRDEV_FREE		      -1
2331da177e4SLinus Torvalds #define TW_MAX_CDB_LEN			      16
2341da177e4SLinus Torvalds 
2351da177e4SLinus Torvalds /* Bitmask macros to eliminate bitfields */
2361da177e4SLinus Torvalds 
2371da177e4SLinus Torvalds /* opcode: 5, sgloffset: 3 */
2381da177e4SLinus Torvalds #define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
2391da177e4SLinus Torvalds #define TW_SGL_OUT(x) ((x >> 5) & 0x7)
2401da177e4SLinus Torvalds 
2411da177e4SLinus Torvalds /* reserved_1: 4, response_id: 8, reserved_2: 20 */
2421da177e4SLinus Torvalds #define TW_RESID_OUT(x) ((x >> 4) & 0xff)
2431da177e4SLinus Torvalds 
2441da177e4SLinus Torvalds /* unit: 4, host_id: 4 */
2451da177e4SLinus Torvalds #define TW_UNITHOST_IN(x,y) ((x << 4) | ( y & 0xf))
2461da177e4SLinus Torvalds #define TW_UNIT_OUT(x) (x & 0xf)
2471da177e4SLinus Torvalds 
2481da177e4SLinus Torvalds /* Macros */
2491da177e4SLinus Torvalds #define TW_CONTROL_REG_ADDR(x) (x->base_addr)
2501da177e4SLinus Torvalds #define TW_STATUS_REG_ADDR(x) (x->base_addr + 0x4)
2511da177e4SLinus Torvalds #define TW_COMMAND_QUEUE_REG_ADDR(x) (x->base_addr + 0x8)
2521da177e4SLinus Torvalds #define TW_RESPONSE_QUEUE_REG_ADDR(x) (x->base_addr + 0xC)
2538148dfbaSHannes Reinecke #define TW_CLEAR_ALL_INTERRUPTS(x)					\
2548148dfbaSHannes Reinecke 	(outl(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
2558148dfbaSHannes Reinecke #define TW_CLEAR_ATTENTION_INTERRUPT(x)					\
2568148dfbaSHannes Reinecke 	(outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
2578148dfbaSHannes Reinecke #define TW_CLEAR_HOST_INTERRUPT(x)					\
2588148dfbaSHannes Reinecke 	(outl(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
2598148dfbaSHannes Reinecke #define TW_DISABLE_INTERRUPTS(x)					\
2608148dfbaSHannes Reinecke 	(outl(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
2618148dfbaSHannes Reinecke #define TW_ENABLE_AND_CLEAR_INTERRUPTS(x)				\
2628148dfbaSHannes Reinecke 	(outl(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |			\
2638148dfbaSHannes Reinecke 	      TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |			\
2648148dfbaSHannes Reinecke 	      TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
2658148dfbaSHannes Reinecke #define TW_MASK_COMMAND_INTERRUPT(x)					\
2668148dfbaSHannes Reinecke 	(outl(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
2678148dfbaSHannes Reinecke #define TW_UNMASK_COMMAND_INTERRUPT(x)					\
2688148dfbaSHannes Reinecke 	(outl(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
2691da177e4SLinus Torvalds #define TW_SOFT_RESET(x) (outl(TW_CONTROL_ISSUE_SOFT_RESET |		\
2701da177e4SLinus Torvalds 			       TW_CONTROL_CLEAR_HOST_INTERRUPT |	\
2711da177e4SLinus Torvalds 			       TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |	\
2721da177e4SLinus Torvalds 			       TW_CONTROL_MASK_COMMAND_INTERRUPT |	\
2731da177e4SLinus Torvalds 			       TW_CONTROL_MASK_RESPONSE_INTERRUPT |	\
2741da177e4SLinus Torvalds 			       TW_CONTROL_CLEAR_ERROR_STATUS |		\
2751da177e4SLinus Torvalds 			       TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
2761da177e4SLinus Torvalds #define TW_STATUS_ERRORS(x)				\
2771da177e4SLinus Torvalds 	(((x & TW_STATUS_PCI_ABORT) ||			\
2781da177e4SLinus Torvalds 	  (x & TW_STATUS_PCI_PARITY_ERROR) ||		\
2791da177e4SLinus Torvalds 	  (x & TW_STATUS_QUEUE_ERROR) ||		\
2801da177e4SLinus Torvalds 	  (x & TW_STATUS_MICROCONTROLLER_ERROR)) &&	\
2811da177e4SLinus Torvalds 	 (x & TW_STATUS_MICROCONTROLLER_READY))
2821da177e4SLinus Torvalds 
2831da177e4SLinus Torvalds #ifdef TW_DEBUG
2841da177e4SLinus Torvalds #define dprintk(msg...) printk(msg)
2851da177e4SLinus Torvalds #else
2861da177e4SLinus Torvalds #define dprintk(msg...) do { } while(0)
2871da177e4SLinus Torvalds #endif
2881da177e4SLinus Torvalds 
2891da177e4SLinus Torvalds #pragma pack(1)
2901da177e4SLinus Torvalds 
2911da177e4SLinus Torvalds /* Scatter Gather List Entry */
2921da177e4SLinus Torvalds typedef struct TAG_TW_SG_Entry {
2931da177e4SLinus Torvalds 	u32 address;
2941da177e4SLinus Torvalds 	u32 length;
2951da177e4SLinus Torvalds } TW_SG_Entry;
2961da177e4SLinus Torvalds 
2971da177e4SLinus Torvalds typedef unsigned char TW_Sector[512];
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds /* Command Packet */
3001da177e4SLinus Torvalds typedef struct TW_Command {
3011da177e4SLinus Torvalds 	unsigned char opcode__sgloffset;
3021da177e4SLinus Torvalds 	unsigned char size;
3031da177e4SLinus Torvalds 	unsigned char request_id;
3041da177e4SLinus Torvalds 	unsigned char unit__hostid;
3051da177e4SLinus Torvalds 	/* Second DWORD */
3061da177e4SLinus Torvalds 	unsigned char status;
3071da177e4SLinus Torvalds 	unsigned char flags;
3081da177e4SLinus Torvalds 	union {
3091da177e4SLinus Torvalds 		unsigned short block_count;
3101da177e4SLinus Torvalds 		unsigned short parameter_count;
3111da177e4SLinus Torvalds 		unsigned short message_credits;
3121da177e4SLinus Torvalds 	} byte6;
3131da177e4SLinus Torvalds 	union {
3141da177e4SLinus Torvalds 		struct {
3151da177e4SLinus Torvalds 			u32 lba;
3161da177e4SLinus Torvalds 			TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
3171da177e4SLinus Torvalds 			u32 padding;	/* pad to 512 bytes */
3181da177e4SLinus Torvalds 		} io;
3191da177e4SLinus Torvalds 		struct {
3201da177e4SLinus Torvalds 			TW_SG_Entry sgl[TW_MAX_SGL_LENGTH];
3211da177e4SLinus Torvalds 			u32 padding[2];
3221da177e4SLinus Torvalds 		} param;
3231da177e4SLinus Torvalds 		struct {
3241da177e4SLinus Torvalds 			u32 response_queue_pointer;
3251da177e4SLinus Torvalds 			u32 padding[125];
3261da177e4SLinus Torvalds 		} init_connection;
3271da177e4SLinus Torvalds 		struct {
3281da177e4SLinus Torvalds 			char version[504];
3291da177e4SLinus Torvalds 		} ioctl_miniport_version;
3301da177e4SLinus Torvalds 	} byte8;
3311da177e4SLinus Torvalds } TW_Command;
3321da177e4SLinus Torvalds 
3331da177e4SLinus Torvalds #pragma pack()
3341da177e4SLinus Torvalds 
3351da177e4SLinus Torvalds typedef struct TAG_TW_Ioctl {
3361da177e4SLinus Torvalds 	unsigned char opcode;
3371da177e4SLinus Torvalds 	unsigned short table_id;
3381da177e4SLinus Torvalds 	unsigned char parameter_id;
3391da177e4SLinus Torvalds 	unsigned char parameter_size_bytes;
3401da177e4SLinus Torvalds 	unsigned char unit_index;
3411da177e4SLinus Torvalds 	unsigned char data[1];
3421da177e4SLinus Torvalds } TW_Ioctl;
3431da177e4SLinus Torvalds 
3441da177e4SLinus Torvalds #pragma pack(1)
3451da177e4SLinus Torvalds 
3461da177e4SLinus Torvalds /* Structure for new chardev ioctls */
3471da177e4SLinus Torvalds typedef struct TAG_TW_New_Ioctl {
3481da177e4SLinus Torvalds 	unsigned int data_buffer_length;
3491da177e4SLinus Torvalds 	unsigned char padding [508];
3501da177e4SLinus Torvalds 	TW_Command firmware_command;
351*0fb9125eSGustavo A. R. Silva 	char data_buffer[];
3521da177e4SLinus Torvalds } TW_New_Ioctl;
3531da177e4SLinus Torvalds 
3541da177e4SLinus Torvalds /* GetParam descriptor */
3551da177e4SLinus Torvalds typedef struct {
3561da177e4SLinus Torvalds 	unsigned short	table_id;
3571da177e4SLinus Torvalds 	unsigned char	parameter_id;
3581da177e4SLinus Torvalds 	unsigned char	parameter_size_bytes;
3591da177e4SLinus Torvalds 	unsigned char	data[1];
3601da177e4SLinus Torvalds } TW_Param, *PTW_Param;
3611da177e4SLinus Torvalds 
3621da177e4SLinus Torvalds /* Response queue */
3631da177e4SLinus Torvalds typedef union TAG_TW_Response_Queue {
3641da177e4SLinus Torvalds 	u32 response_id;
3651da177e4SLinus Torvalds 	u32 value;
3661da177e4SLinus Torvalds } TW_Response_Queue;
3671da177e4SLinus Torvalds 
3681da177e4SLinus Torvalds typedef int TW_Cmd_State;
3691da177e4SLinus Torvalds 
3701da177e4SLinus Torvalds #define TW_S_INITIAL   0x1  /* Initial state */
3711da177e4SLinus Torvalds #define TW_S_STARTED   0x2  /* Id in use */
3721da177e4SLinus Torvalds #define TW_S_POSTED    0x4  /* Posted to the controller */
3731da177e4SLinus Torvalds #define TW_S_PENDING   0x8  /* Waiting to be posted in isr */
3741da177e4SLinus Torvalds #define TW_S_COMPLETED 0x10 /* Completed by isr */
3751da177e4SLinus Torvalds #define TW_S_FINISHED  0x20 /* I/O completely done */
3761da177e4SLinus Torvalds #define TW_START_MASK (TW_S_STARTED | TW_S_POSTED | TW_S_PENDING | TW_S_COMPLETED)
3771da177e4SLinus Torvalds 
3781da177e4SLinus Torvalds /* Command header for ATA pass-thru */
3791da177e4SLinus Torvalds typedef struct TAG_TW_Passthru
3801da177e4SLinus Torvalds {
3811da177e4SLinus Torvalds 	unsigned char opcode__sgloffset;
3821da177e4SLinus Torvalds 	unsigned char size;
3831da177e4SLinus Torvalds 	unsigned char request_id;
3841da177e4SLinus Torvalds 	unsigned char aport__hostid;
3851da177e4SLinus Torvalds 	unsigned char status;
3861da177e4SLinus Torvalds 	unsigned char flags;
3871da177e4SLinus Torvalds 	unsigned short param;
3881da177e4SLinus Torvalds 	unsigned short features;
3891da177e4SLinus Torvalds 	unsigned short sector_count;
3901da177e4SLinus Torvalds 	unsigned short sector_num;
3911da177e4SLinus Torvalds 	unsigned short cylinder_lo;
3921da177e4SLinus Torvalds 	unsigned short cylinder_hi;
3931da177e4SLinus Torvalds 	unsigned char drive_head;
3941da177e4SLinus Torvalds 	unsigned char command;
3951da177e4SLinus Torvalds 	TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX];
3961da177e4SLinus Torvalds 	unsigned char padding[12];
3971da177e4SLinus Torvalds } TW_Passthru;
3981da177e4SLinus Torvalds 
3994bfaa5c4SArnd Bergmann #pragma pack()
4004bfaa5c4SArnd Bergmann 
4011da177e4SLinus Torvalds typedef struct TAG_TW_Device_Extension {
4021da177e4SLinus Torvalds 	u32			base_addr;
4031da177e4SLinus Torvalds 	unsigned long		*alignment_virtual_address[TW_Q_LENGTH];
4041da177e4SLinus Torvalds 	unsigned long		alignment_physical_address[TW_Q_LENGTH];
4051da177e4SLinus Torvalds 	int			is_unit_present[TW_MAX_UNITS];
4061da177e4SLinus Torvalds 	unsigned long		*command_packet_virtual_address[TW_Q_LENGTH];
4071da177e4SLinus Torvalds 	unsigned long		command_packet_physical_address[TW_Q_LENGTH];
4081da177e4SLinus Torvalds 	struct pci_dev		*tw_pci_dev;
4091da177e4SLinus Torvalds 	struct scsi_cmnd	*srb[TW_Q_LENGTH];
4101da177e4SLinus Torvalds 	unsigned char		free_queue[TW_Q_LENGTH];
4111da177e4SLinus Torvalds 	unsigned char		free_head;
4121da177e4SLinus Torvalds 	unsigned char		free_tail;
4131da177e4SLinus Torvalds 	unsigned char		pending_queue[TW_Q_LENGTH];
4141da177e4SLinus Torvalds 	unsigned char		pending_head;
4151da177e4SLinus Torvalds 	unsigned char		pending_tail;
4161da177e4SLinus Torvalds 	TW_Cmd_State		state[TW_Q_LENGTH];
4171da177e4SLinus Torvalds 	u32			posted_request_count;
4181da177e4SLinus Torvalds 	u32			max_posted_request_count;
4191da177e4SLinus Torvalds 	u32			request_count_marked_pending;
4201da177e4SLinus Torvalds 	u32			pending_request_count;
4211da177e4SLinus Torvalds 	u32			max_pending_request_count;
4221da177e4SLinus Torvalds 	u32			max_sgl_entries;
4231da177e4SLinus Torvalds 	u32			sgl_entries;
4241da177e4SLinus Torvalds 	u32			num_resets;
4251da177e4SLinus Torvalds 	u32			sector_count;
4261da177e4SLinus Torvalds 	u32			max_sector_count;
4271da177e4SLinus Torvalds 	u32			aen_count;
4281da177e4SLinus Torvalds 	struct Scsi_Host	*host;
429a12e25bdSJes Sorensen 	struct mutex		ioctl_lock;
4301da177e4SLinus Torvalds 	unsigned short		aen_queue[TW_Q_LENGTH];
4311da177e4SLinus Torvalds 	unsigned char		aen_head;
4321da177e4SLinus Torvalds 	unsigned char		aen_tail;
4331da177e4SLinus Torvalds 	volatile long		flags; /* long req'd for set_bit --RR */
4341da177e4SLinus Torvalds 	int			reset_print;
4351da177e4SLinus Torvalds 	volatile int		chrdev_request_id;
4361da177e4SLinus Torvalds 	wait_queue_head_t	ioctl_wqueue;
4371da177e4SLinus Torvalds } TW_Device_Extension;
4381da177e4SLinus Torvalds 
4391da177e4SLinus Torvalds #endif /* _3W_XXXX_H */
440