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