Back to home page

OSCL-LXR

 
 

    


0001 /*
0002    3w-9xxx.h -- 3ware 9000 Storage Controller device driver for Linux.
0003 
0004    Written By: Adam Radford <aradford@gmail.com>
0005    Modifications By: Tom Couch
0006 
0007    Copyright (C) 2004-2009 Applied Micro Circuits Corporation.
0008    Copyright (C) 2010 LSI Corporation.
0009 
0010    This program is free software; you can redistribute it and/or modify
0011    it under the terms of the GNU General Public License as published by
0012    the Free Software Foundation; version 2 of the License.
0013 
0014    This program is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017    GNU General Public License for more details.
0018 
0019    NO WARRANTY
0020    THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
0021    CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
0022    LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
0023    MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
0024    solely responsible for determining the appropriateness of using and
0025    distributing the Program and assumes all risks associated with its
0026    exercise of rights under this Agreement, including but not limited to
0027    the risks and costs of program errors, damage to or loss of data,
0028    programs or equipment, and unavailability or interruption of operations.
0029 
0030    DISCLAIMER OF LIABILITY
0031    NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
0032    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
0033    DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
0034    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
0035    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
0036    USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
0037    HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
0038 
0039    You should have received a copy of the GNU General Public License
0040    along with this program; if not, write to the Free Software
0041    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0042 
0043    Bugs/Comments/Suggestions should be mailed to:
0044    aradford@gmail.com
0045 */
0046 
0047 #ifndef _3W_9XXX_H
0048 #define _3W_9XXX_H
0049 
0050 /* AEN string type */
0051 typedef struct TAG_twa_message_type {
0052     unsigned int   code;
0053     char           *text;
0054 } twa_message_type;
0055 
0056 /* AEN strings */
0057 static twa_message_type twa_aen_table[] = {
0058     {0x0000, "AEN queue empty"},
0059     {0x0001, "Controller reset occurred"},
0060     {0x0002, "Degraded unit detected"},
0061     {0x0003, "Controller error occurred"},
0062     {0x0004, "Background rebuild failed"},
0063     {0x0005, "Background rebuild done"},
0064     {0x0006, "Incomplete unit detected"},
0065     {0x0007, "Background initialize done"},
0066     {0x0008, "Unclean shutdown detected"},
0067     {0x0009, "Drive timeout detected"},
0068     {0x000A, "Drive error detected"},
0069     {0x000B, "Rebuild started"},
0070     {0x000C, "Background initialize started"},
0071     {0x000D, "Entire logical unit was deleted"},
0072     {0x000E, "Background initialize failed"},
0073     {0x000F, "SMART attribute exceeded threshold"},
0074     {0x0010, "Power supply reported AC under range"},
0075     {0x0011, "Power supply reported DC out of range"},
0076     {0x0012, "Power supply reported a malfunction"},
0077     {0x0013, "Power supply predicted malfunction"},
0078     {0x0014, "Battery charge is below threshold"},
0079     {0x0015, "Fan speed is below threshold"},
0080     {0x0016, "Temperature sensor is above threshold"},
0081     {0x0017, "Power supply was removed"},
0082     {0x0018, "Power supply was inserted"},
0083     {0x0019, "Drive was removed from a bay"},
0084     {0x001A, "Drive was inserted into a bay"},
0085     {0x001B, "Drive bay cover door was opened"},
0086     {0x001C, "Drive bay cover door was closed"},
0087     {0x001D, "Product case was opened"},
0088     {0x0020, "Prepare for shutdown (power-off)"},
0089     {0x0021, "Downgrade UDMA mode to lower speed"},
0090     {0x0022, "Upgrade UDMA mode to higher speed"},
0091     {0x0023, "Sector repair completed"},
0092     {0x0024, "Sbuf memory test failed"},
0093     {0x0025, "Error flushing cached write data to array"},
0094     {0x0026, "Drive reported data ECC error"},
0095     {0x0027, "DCB has checksum error"},
0096     {0x0028, "DCB version is unsupported"},
0097     {0x0029, "Background verify started"},
0098     {0x002A, "Background verify failed"},
0099     {0x002B, "Background verify done"},
0100     {0x002C, "Bad sector overwritten during rebuild"},
0101     {0x002D, "Background rebuild error on source drive"},
0102     {0x002E, "Replace failed because replacement drive too small"},
0103     {0x002F, "Verify failed because array was never initialized"},
0104     {0x0030, "Unsupported ATA drive"},
0105     {0x0031, "Synchronize host/controller time"},
0106     {0x0032, "Spare capacity is inadequate for some units"},
0107     {0x0033, "Background migration started"},
0108     {0x0034, "Background migration failed"},
0109     {0x0035, "Background migration done"},
0110     {0x0036, "Verify detected and fixed data/parity mismatch"},
0111     {0x0037, "SO-DIMM incompatible"},
0112     {0x0038, "SO-DIMM not detected"},
0113     {0x0039, "Corrected Sbuf ECC error"},
0114     {0x003A, "Drive power on reset detected"},
0115     {0x003B, "Background rebuild paused"},
0116     {0x003C, "Background initialize paused"},
0117     {0x003D, "Background verify paused"},
0118     {0x003E, "Background migration paused"},
0119     {0x003F, "Corrupt flash file system detected"},
0120     {0x0040, "Flash file system repaired"},
0121     {0x0041, "Unit number assignments were lost"},
0122     {0x0042, "Error during read of primary DCB"},
0123     {0x0043, "Latent error found in backup DCB"},
0124     {0x00FC, "Recovered/finished array membership update"},
0125     {0x00FD, "Handler lockup"},
0126     {0x00FE, "Retrying PCI transfer"},
0127     {0x00FF, "AEN queue is full"},
0128     {0xFFFFFFFF, (char*) 0}
0129 };
0130 
0131 /* AEN severity table */
0132 static char *twa_aen_severity_table[] =
0133 {
0134     "None", "ERROR", "WARNING", "INFO", "DEBUG", (char*) 0
0135 };
0136 
0137 /* Error strings */
0138 static twa_message_type twa_error_table[] = {
0139     {0x0100, "SGL entry contains zero data"},
0140     {0x0101, "Invalid command opcode"},
0141     {0x0102, "SGL entry has unaligned address"},
0142     {0x0103, "SGL size does not match command"},
0143     {0x0104, "SGL entry has illegal length"},
0144     {0x0105, "Command packet is not aligned"},
0145     {0x0106, "Invalid request ID"},
0146     {0x0107, "Duplicate request ID"},
0147     {0x0108, "ID not locked"},
0148     {0x0109, "LBA out of range"},
0149     {0x010A, "Logical unit not supported"},
0150     {0x010B, "Parameter table does not exist"},
0151     {0x010C, "Parameter index does not exist"},
0152     {0x010D, "Invalid field in CDB"},
0153     {0x010E, "Specified port has invalid drive"},
0154     {0x010F, "Parameter item size mismatch"},
0155     {0x0110, "Failed memory allocation"},
0156     {0x0111, "Memory request too large"},
0157     {0x0112, "Out of memory segments"},
0158     {0x0113, "Invalid address to deallocate"},
0159     {0x0114, "Out of memory"},
0160     {0x0115, "Out of heap"},
0161     {0x0120, "Double degrade"},
0162     {0x0121, "Drive not degraded"},
0163     {0x0122, "Reconstruct error"},
0164     {0x0123, "Replace not accepted"},
0165     {0x0124, "Replace drive capacity too small"},
0166     {0x0125, "Sector count not allowed"},
0167     {0x0126, "No spares left"},
0168     {0x0127, "Reconstruct error"},
0169     {0x0128, "Unit is offline"},
0170     {0x0129, "Cannot update status to DCB"},
0171     {0x0130, "Invalid stripe handle"},
0172     {0x0131, "Handle that was not locked"},
0173     {0x0132, "Handle that was not empty"},
0174     {0x0133, "Handle has different owner"},
0175     {0x0140, "IPR has parent"},
0176     {0x0150, "Illegal Pbuf address alignment"},
0177     {0x0151, "Illegal Pbuf transfer length"},
0178     {0x0152, "Illegal Sbuf address alignment"},
0179     {0x0153, "Illegal Sbuf transfer length"},
0180     {0x0160, "Command packet too large"},
0181     {0x0161, "SGL exceeds maximum length"},
0182     {0x0162, "SGL has too many entries"},
0183     {0x0170, "Insufficient resources for rebuilder"},
0184     {0x0171, "Verify error (data != parity)"},
0185     {0x0180, "Requested segment not in directory of this DCB"},
0186     {0x0181, "DCB segment has unsupported version"},
0187     {0x0182, "DCB segment has checksum error"},
0188     {0x0183, "DCB support (settings) segment invalid"},
0189     {0x0184, "DCB UDB (unit descriptor block) segment invalid"},
0190     {0x0185, "DCB GUID (globally unique identifier) segment invalid"},
0191     {0x01A0, "Could not clear Sbuf"},
0192     {0x01C0, "Flash identify failed"},
0193     {0x01C1, "Flash out of bounds"},
0194     {0x01C2, "Flash verify error"},
0195     {0x01C3, "Flash file object not found"},
0196     {0x01C4, "Flash file already present"},
0197     {0x01C5, "Flash file system full"},
0198     {0x01C6, "Flash file not present"},
0199     {0x01C7, "Flash file size error"},
0200     {0x01C8, "Bad flash file checksum"},
0201     {0x01CA, "Corrupt flash file system detected"},
0202     {0x01D0, "Invalid field in parameter list"},
0203     {0x01D1, "Parameter list length error"},
0204     {0x01D2, "Parameter item is not changeable"},
0205     {0x01D3, "Parameter item is not saveable"},
0206     {0x0200, "UDMA CRC error"},
0207     {0x0201, "Internal CRC error"},
0208     {0x0202, "Data ECC error"},
0209     {0x0203, "ADP level 1 error"},
0210     {0x0204, "Port timeout"},
0211     {0x0205, "Drive power on reset"},
0212     {0x0206, "ADP level 2 error"},
0213     {0x0207, "Soft reset failed"},
0214     {0x0208, "Drive not ready"},
0215     {0x0209, "Unclassified port error"},
0216     {0x020A, "Drive aborted command"},
0217     {0x0210, "Internal CRC error"},
0218     {0x0211, "PCI abort error"},
0219     {0x0212, "PCI parity error"},
0220     {0x0213, "Port handler error"},
0221     {0x0214, "Token interrupt count error"},
0222     {0x0215, "Timeout waiting for PCI transfer"},
0223     {0x0216, "Corrected buffer ECC"},
0224     {0x0217, "Uncorrected buffer ECC"},
0225     {0x0230, "Unsupported command during flash recovery"},
0226     {0x0231, "Next image buffer expected"},
0227     {0x0232, "Binary image architecture incompatible"},
0228     {0x0233, "Binary image has no signature"},
0229     {0x0234, "Binary image has bad checksum"},
0230     {0x0235, "Image downloaded overflowed buffer"},
0231     {0x0240, "I2C device not found"},
0232     {0x0241, "I2C transaction aborted"},
0233     {0x0242, "SO-DIMM parameter(s) incompatible using defaults"},
0234     {0x0243, "SO-DIMM unsupported"},
0235     {0x0248, "SPI transfer status error"},
0236     {0x0249, "SPI transfer timeout error"},
0237     {0x0250, "Invalid unit descriptor size in CreateUnit"},
0238     {0x0251, "Unit descriptor size exceeds data buffer in CreateUnit"},
0239     {0x0252, "Invalid value in CreateUnit descriptor"},
0240     {0x0253, "Inadequate disk space to support descriptor in CreateUnit"},
0241     {0x0254, "Unable to create data channel for this unit descriptor"},
0242     {0x0255, "CreateUnit descriptor specifies a drive already in use"},
0243     {0x0256, "Unable to write configuration to all disks during CreateUnit"},
0244     {0x0257, "CreateUnit does not support this descriptor version"},
0245     {0x0258, "Invalid subunit for RAID 0 or 5 in CreateUnit"},
0246     {0x0259, "Too many descriptors in CreateUnit"},
0247     {0x025A, "Invalid configuration specified in CreateUnit descriptor"},
0248     {0x025B, "Invalid LBA offset specified in CreateUnit descriptor"},
0249     {0x025C, "Invalid stripelet size specified in CreateUnit descriptor"},
0250     {0x0260, "SMART attribute exceeded threshold"},
0251     {0xFFFFFFFF, (char*) 0}
0252 };
0253 
0254 /* Control register bit definitions */
0255 #define TW_CONTROL_CLEAR_HOST_INTERRUPT        0x00080000
0256 #define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT   0x00040000
0257 #define TW_CONTROL_MASK_COMMAND_INTERRUPT      0x00020000
0258 #define TW_CONTROL_MASK_RESPONSE_INTERRUPT     0x00010000
0259 #define TW_CONTROL_UNMASK_COMMAND_INTERRUPT    0x00008000
0260 #define TW_CONTROL_UNMASK_RESPONSE_INTERRUPT   0x00004000
0261 #define TW_CONTROL_CLEAR_ERROR_STATUS          0x00000200
0262 #define TW_CONTROL_ISSUE_SOFT_RESET        0x00000100
0263 #define TW_CONTROL_ENABLE_INTERRUPTS           0x00000080
0264 #define TW_CONTROL_DISABLE_INTERRUPTS          0x00000040
0265 #define TW_CONTROL_ISSUE_HOST_INTERRUPT        0x00000020
0266 #define TW_CONTROL_CLEAR_PARITY_ERROR          0x00800000
0267 #define TW_CONTROL_CLEAR_QUEUE_ERROR           0x00400000
0268 #define TW_CONTROL_CLEAR_PCI_ABORT         0x00100000
0269 
0270 /* Status register bit definitions */
0271 #define TW_STATUS_MAJOR_VERSION_MASK           0xF0000000
0272 #define TW_STATUS_MINOR_VERSION_MASK           0x0F000000
0273 #define TW_STATUS_PCI_PARITY_ERROR         0x00800000
0274 #define TW_STATUS_QUEUE_ERROR              0x00400000
0275 #define TW_STATUS_MICROCONTROLLER_ERROR        0x00200000
0276 #define TW_STATUS_PCI_ABORT            0x00100000
0277 #define TW_STATUS_HOST_INTERRUPT           0x00080000
0278 #define TW_STATUS_ATTENTION_INTERRUPT          0x00040000
0279 #define TW_STATUS_COMMAND_INTERRUPT        0x00020000
0280 #define TW_STATUS_RESPONSE_INTERRUPT           0x00010000
0281 #define TW_STATUS_COMMAND_QUEUE_FULL           0x00008000
0282 #define TW_STATUS_RESPONSE_QUEUE_EMPTY         0x00004000
0283 #define TW_STATUS_MICROCONTROLLER_READY        0x00002000
0284 #define TW_STATUS_COMMAND_QUEUE_EMPTY          0x00001000
0285 #define TW_STATUS_EXPECTED_BITS            0x00002000
0286 #define TW_STATUS_UNEXPECTED_BITS          0x00F00000
0287 #define TW_STATUS_VALID_INTERRUPT          0x00DF0000
0288 
0289 /* PCI related defines */
0290 #define TW_PCI_CLEAR_PARITY_ERRORS 0xc100
0291 #define TW_PCI_CLEAR_PCI_ABORT     0x2000
0292 
0293 /* Command packet opcodes used by the driver */
0294 #define TW_OP_INIT_CONNECTION   0x1
0295 #define TW_OP_GET_PARAM     0x12
0296 #define TW_OP_SET_PARAM     0x13
0297 #define TW_OP_EXECUTE_SCSI  0x10
0298 #define TW_OP_DOWNLOAD_FIRMWARE 0x16
0299 #define TW_OP_RESET     0x1C
0300 
0301 /* Asynchronous Event Notification (AEN) codes used by the driver */
0302 #define TW_AEN_QUEUE_EMPTY  0x0000
0303 #define TW_AEN_SOFT_RESET   0x0001
0304 #define TW_AEN_SYNC_TIME_WITH_HOST 0x031
0305 #define TW_AEN_SEVERITY_ERROR   0x1
0306 #define TW_AEN_SEVERITY_DEBUG    0x4
0307 #define TW_AEN_NOT_RETRIEVED 0x1
0308 #define TW_AEN_RETRIEVED 0x2
0309 
0310 /* Command state defines */
0311 #define TW_S_INITIAL   0x1  /* Initial state */
0312 #define TW_S_STARTED   0x2  /* Id in use */
0313 #define TW_S_POSTED    0x4  /* Posted to the controller */
0314 #define TW_S_PENDING   0x8  /* Waiting to be posted in isr */
0315 #define TW_S_COMPLETED 0x10 /* Completed by isr */
0316 #define TW_S_FINISHED  0x20 /* I/O completely done */
0317 
0318 /* Compatibility defines */
0319 #define TW_9000_ARCH_ID 0x5
0320 #define TW_CURRENT_DRIVER_SRL 35
0321 #define TW_CURRENT_DRIVER_BUILD 0
0322 #define TW_CURRENT_DRIVER_BRANCH 0
0323 
0324 /* Misc defines */
0325 #define TW_9550SX_DRAIN_COMPLETED         0xFFFF
0326 #define TW_SECTOR_SIZE                512
0327 #define TW_ALIGNMENT_9000             4  /* 4 bytes */
0328 #define TW_ALIGNMENT_9000_SGL             0x3
0329 #define TW_MAX_UNITS                  16
0330 #define TW_MAX_UNITS_9650SE           32
0331 #define TW_INIT_MESSAGE_CREDITS           0x100
0332 #define TW_INIT_COMMAND_PACKET_SIZE       0x3
0333 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED  0x6
0334 #define TW_EXTENDED_INIT_CONNECT          0x2
0335 #define TW_BUNDLED_FW_SAFE_TO_FLASH       0x4
0336 #define TW_CTLR_FW_RECOMMENDS_FLASH       0x8
0337 #define TW_CTLR_FW_COMPATIBLE             0x2
0338 #define TW_BASE_FW_SRL                24
0339 #define TW_BASE_FW_BRANCH             0
0340 #define TW_BASE_FW_BUILD              1
0341 #define TW_FW_SRL_LUNS_SUPPORTED          28
0342 #define TW_Q_LENGTH               256
0343 #define TW_Q_START                0
0344 #define TW_MAX_SLOT               32
0345 #define TW_MAX_RESET_TRIES            2
0346 #define TW_MAX_CMDS_PER_LUN           254
0347 #define TW_MAX_RESPONSE_DRAIN             256
0348 #define TW_MAX_AEN_DRAIN              255
0349 #define TW_IN_RESET               2
0350 #define TW_USING_MSI                  3
0351 #define TW_IN_ATTENTION_LOOP              4
0352 #define TW_MAX_SECTORS                256
0353 #define TW_AEN_WAIT_TIME              1000
0354 #define TW_IOCTL_WAIT_TIME            (1 * HZ) /* 1 second */
0355 #define TW_MAX_CDB_LEN                16
0356 #define TW_ISR_DONT_COMPLETE              2
0357 #define TW_ISR_DONT_RESULT            3
0358 #define TW_IOCTL_CHRDEV_TIMEOUT           60 /* 60 seconds */
0359 #define TW_IOCTL_CHRDEV_FREE              -1
0360 #define TW_COMMAND_OFFSET             128 /* 128 bytes */
0361 #define TW_VERSION_TABLE              0x0402
0362 #define TW_TIMEKEEP_TABLE             0x040A
0363 #define TW_INFORMATION_TABLE              0x0403
0364 #define TW_PARAM_FWVER                3
0365 #define TW_PARAM_FWVER_LENGTH             16
0366 #define TW_PARAM_BIOSVER              4
0367 #define TW_PARAM_BIOSVER_LENGTH           16
0368 #define TW_PARAM_PORTCOUNT            3
0369 #define TW_PARAM_PORTCOUNT_LENGTH         1
0370 #define TW_MIN_SGL_LENGTH             0x200 /* 512 bytes */
0371 #define TW_MAX_SENSE_LENGTH           256
0372 #define TW_EVENT_SOURCE_AEN           0x1000
0373 #define TW_EVENT_SOURCE_COMMAND           0x1001
0374 #define TW_EVENT_SOURCE_PCHIP             0x1002
0375 #define TW_EVENT_SOURCE_DRIVER            0x1003
0376 #define TW_IOCTL_GET_COMPATIBILITY_INFO       0x101
0377 #define TW_IOCTL_GET_LAST_EVENT           0x102
0378 #define TW_IOCTL_GET_FIRST_EVENT          0x103
0379 #define TW_IOCTL_GET_NEXT_EVENT           0x104
0380 #define TW_IOCTL_GET_PREVIOUS_EVENT       0x105
0381 #define TW_IOCTL_GET_LOCK             0x106
0382 #define TW_IOCTL_RELEASE_LOCK             0x107
0383 #define TW_IOCTL_FIRMWARE_PASS_THROUGH        0x108
0384 #define TW_IOCTL_ERROR_STATUS_NOT_LOCKED      0x1001 // Not locked
0385 #define TW_IOCTL_ERROR_STATUS_LOCKED          0x1002 // Already locked
0386 #define TW_IOCTL_ERROR_STATUS_NO_MORE_EVENTS  0x1003 // No more events
0387 #define TW_IOCTL_ERROR_STATUS_AEN_CLOBBER     0x1004 // AEN clobber occurred
0388 #define TW_IOCTL_ERROR_OS_EFAULT          -EFAULT // Bad address
0389 #define TW_IOCTL_ERROR_OS_EINTR           -EINTR  // Interrupted system call
0390 #define TW_IOCTL_ERROR_OS_EINVAL          -EINVAL // Invalid argument
0391 #define TW_IOCTL_ERROR_OS_ENOMEM          -ENOMEM // Out of memory
0392 #define TW_IOCTL_ERROR_OS_ERESTARTSYS         -ERESTARTSYS // Restart system call
0393 #define TW_IOCTL_ERROR_OS_EIO             -EIO // I/O error
0394 #define TW_IOCTL_ERROR_OS_ENOTTY          -ENOTTY // Not a typewriter
0395 #define TW_IOCTL_ERROR_OS_ENODEV          -ENODEV // No such device
0396 #define TW_ALLOCATION_LENGTH              128
0397 #define TW_SENSE_DATA_LENGTH              18
0398 #define TW_STATUS_CHECK_CONDITION         2
0399 #define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED   0x10a
0400 #define TW_ERROR_UNIT_OFFLINE             0x128
0401 #define TW_MESSAGE_SOURCE_CONTROLLER_ERROR    3
0402 #define TW_MESSAGE_SOURCE_CONTROLLER_EVENT    4
0403 #define TW_MESSAGE_SOURCE_LINUX_DRIVER        6
0404 #define TW_DRIVER TW_MESSAGE_SOURCE_LINUX_DRIVER
0405 #define TW_MESSAGE_SOURCE_LINUX_OS        9
0406 #define TW_OS TW_MESSAGE_SOURCE_LINUX_OS
0407 #ifndef PCI_DEVICE_ID_3WARE_9000
0408 #define PCI_DEVICE_ID_3WARE_9000 0x1002
0409 #endif
0410 #ifndef PCI_DEVICE_ID_3WARE_9550SX
0411 #define PCI_DEVICE_ID_3WARE_9550SX 0x1003
0412 #endif
0413 #ifndef PCI_DEVICE_ID_3WARE_9650SE
0414 #define PCI_DEVICE_ID_3WARE_9650SE 0x1004
0415 #endif
0416 #ifndef PCI_DEVICE_ID_3WARE_9690SA
0417 #define PCI_DEVICE_ID_3WARE_9690SA 0x1005
0418 #endif
0419 
0420 /* Bitmask macros to eliminate bitfields */
0421 
0422 /* opcode: 5, reserved: 3 */
0423 #define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))
0424 #define TW_OP_OUT(x) (x & 0x1f)
0425 
0426 /* opcode: 5, sgloffset: 3 */
0427 #define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))
0428 #define TW_SGL_OUT(x) ((x >> 5) & 0x7)
0429 
0430 /* severity: 3, reserved: 5 */
0431 #define TW_SEV_OUT(x) (x & 0x7)
0432 
0433 /* reserved_1: 4, response_id: 8, reserved_2: 20 */
0434 #define TW_RESID_OUT(x) ((x >> 4) & 0xff)
0435 
0436 /* request_id: 12, lun: 4 */
0437 #define TW_REQ_LUN_IN(lun, request_id)          \
0438     cpu_to_le16(((lun << 12) & 0xf000) | (request_id & 0xfff))
0439 #define TW_LUN_OUT(lun) ((le16_to_cpu(lun) >> 12) & 0xf)
0440 
0441 /* Macros */
0442 #define TW_CONTROL_REG_ADDR(x) (x->base_addr)
0443 #define TW_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + 0x4)
0444 #define TW_COMMAND_QUEUE_REG_ADDR(x) \
0445     (sizeof(dma_addr_t) > 4 ? ((unsigned char __iomem *)x->base_addr + 0x20) : ((unsigned char __iomem *)x->base_addr + 0x8))
0446 #define TW_COMMAND_QUEUE_REG_ADDR_LARGE(x) \
0447     ((unsigned char __iomem *)x->base_addr + 0x20)
0448 #define TW_RESPONSE_QUEUE_REG_ADDR(x) \
0449     ((unsigned char __iomem *)x->base_addr + 0xC)
0450 #define TW_RESPONSE_QUEUE_REG_ADDR_LARGE(x) \
0451     ((unsigned char __iomem *)x->base_addr + 0x30)
0452 #define TW_CLEAR_ALL_INTERRUPTS(x) \
0453     (writel(TW_STATUS_VALID_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
0454 #define TW_CLEAR_ATTENTION_INTERRUPT(x) \
0455     (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
0456 #define TW_CLEAR_HOST_INTERRUPT(x) \
0457     (writel(TW_CONTROL_CLEAR_HOST_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
0458 #define TW_DISABLE_INTERRUPTS(x) \
0459     (writel(TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
0460 #define TW_ENABLE_AND_CLEAR_INTERRUPTS(x)               \
0461     (writel(TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |          \
0462         TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |          \
0463         TW_CONTROL_ENABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
0464 #define TW_MASK_COMMAND_INTERRUPT(x)                    \
0465     (writel(TW_CONTROL_MASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
0466 #define TW_UNMASK_COMMAND_INTERRUPT(x)                  \
0467     (writel(TW_CONTROL_UNMASK_COMMAND_INTERRUPT, TW_CONTROL_REG_ADDR(x)))
0468 #define TW_SOFT_RESET(x) (writel(TW_CONTROL_ISSUE_SOFT_RESET |  \
0469             TW_CONTROL_CLEAR_HOST_INTERRUPT | \
0470             TW_CONTROL_CLEAR_ATTENTION_INTERRUPT | \
0471             TW_CONTROL_MASK_COMMAND_INTERRUPT | \
0472             TW_CONTROL_MASK_RESPONSE_INTERRUPT | \
0473             TW_CONTROL_CLEAR_ERROR_STATUS | \
0474             TW_CONTROL_DISABLE_INTERRUPTS, TW_CONTROL_REG_ADDR(x)))
0475 #define TW_PRINTK(h,a,b,c) { \
0476 if (h) \
0477 printk(KERN_WARNING "3w-9xxx: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \
0478 else \
0479 printk(KERN_WARNING "3w-9xxx: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \
0480 }
0481 #define TW_MAX_LUNS(srl) (srl < TW_FW_SRL_LUNS_SUPPORTED ? 1 : 16)
0482 #define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 5 : 4)
0483 #define TW_APACHE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 72 : 109)
0484 #define TW_ESCALADE_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 41 : 62)
0485 #define TW_PADDING_LENGTH (sizeof(dma_addr_t) > 4 ? 8 : 0)
0486 
0487 #if IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)
0488 typedef __le64 twa_addr_t;
0489 #define TW_CPU_TO_SGL(x) cpu_to_le64(x)
0490 #else
0491 typedef __le32 twa_addr_t;
0492 #define TW_CPU_TO_SGL(x) cpu_to_le32(x)
0493 #endif
0494 
0495 /* Scatter Gather List Entry */
0496 typedef struct TAG_TW_SG_Entry {
0497     twa_addr_t  address;
0498     __le32      length;
0499 } __packed TW_SG_Entry;
0500 
0501 /* Command Packet */
0502 typedef struct TW_Command {
0503     u8  opcode__sgloffset;
0504     u8  size;
0505     u8  request_id;
0506     u8  unit__hostid;
0507     /* Second DWORD */
0508     u8  status;
0509     u8  flags;
0510     union {
0511         __le16  block_count;
0512         __le16  parameter_count;
0513     } byte6_offset;
0514     union {
0515         struct {
0516             __le32      lba;
0517             TW_SG_Entry sgl[TW_ESCALADE_MAX_SGL_LENGTH];
0518             twa_addr_t  padding;
0519         } io;
0520         struct {
0521             TW_SG_Entry sgl[TW_ESCALADE_MAX_SGL_LENGTH];
0522             __le32      padding;
0523             twa_addr_t  padding2;
0524         } param;
0525     } byte8_offset;
0526 } TW_Command;
0527 
0528 /* Command Packet for 9000+ controllers */
0529 typedef struct TAG_TW_Command_Apache {
0530     u8      opcode__reserved;
0531     u8      unit;
0532     __le16      request_id__lunl;
0533     u8      status;
0534     u8      sgl_offset;
0535     __le16      sgl_entries__lunh;
0536     u8      cdb[16];
0537     TW_SG_Entry sg_list[TW_APACHE_MAX_SGL_LENGTH];
0538     u8      padding[TW_PADDING_LENGTH];
0539 } TW_Command_Apache;
0540 
0541 /* New command packet header */
0542 typedef struct TAG_TW_Command_Apache_Header {
0543     unsigned char sense_data[TW_SENSE_DATA_LENGTH];
0544     struct {
0545         u8  reserved[4];
0546         __le16  error;
0547         u8  padding;
0548         u8  severity__reserved;
0549     } status_block;
0550     unsigned char err_specific_desc[98];
0551     struct {
0552         u8  size_header;
0553         u8  reserved[2];
0554         u8  size_sense;
0555     } header_desc;
0556 } TW_Command_Apache_Header;
0557 
0558 /* This struct is a union of the 2 command packets */
0559 typedef struct TAG_TW_Command_Full {
0560     TW_Command_Apache_Header header;
0561     union {
0562         TW_Command oldcommand;
0563         TW_Command_Apache newcommand;
0564     } command;
0565 } TW_Command_Full;
0566 
0567 /* Initconnection structure */
0568 typedef struct TAG_TW_Initconnect {
0569     u8  opcode__reserved;
0570     u8  size;
0571     u8  request_id;
0572     u8  res2;
0573     u8  status;
0574     u8  flags;
0575     __le16  message_credits;
0576     __le32  features;
0577     __le16  fw_srl;
0578     __le16  fw_arch_id;
0579     __le16  fw_branch;
0580     __le16  fw_build;
0581     __le32  result;
0582 } TW_Initconnect;
0583 
0584 /* Event info structure */
0585 typedef struct TAG_TW_Event
0586 {
0587     unsigned int sequence_id;
0588     unsigned int time_stamp_sec;
0589     unsigned short aen_code;
0590     unsigned char severity;
0591     unsigned char retrieved;
0592     unsigned char repeat_count;
0593     unsigned char parameter_len;
0594     unsigned char parameter_data[98];
0595 } TW_Event;
0596 
0597 typedef struct TAG_TW_Ioctl_Driver_Command {
0598     unsigned int control_code;
0599     unsigned int status;
0600     unsigned int unique_id;
0601     unsigned int sequence_id;
0602     unsigned int os_specific;
0603     unsigned int buffer_length;
0604 } TW_Ioctl_Driver_Command;
0605 
0606 typedef struct TAG_TW_Ioctl_Apache {
0607     TW_Ioctl_Driver_Command driver_command;
0608     char padding[488];
0609     TW_Command_Full firmware_command;
0610     char data_buffer[];
0611 } TW_Ioctl_Buf_Apache;
0612 
0613 /* Lock structure for ioctl get/release lock */
0614 typedef struct TAG_TW_Lock {
0615     unsigned long timeout_msec;
0616     unsigned long time_remaining_msec;
0617     unsigned long force_flag;
0618 } TW_Lock;
0619 
0620 /* GetParam descriptor */
0621 typedef struct {
0622     __le16  table_id;
0623     __le16  parameter_id;
0624     __le16  parameter_size_bytes;
0625     __le16  actual_parameter_size_bytes;
0626     u8  data[];
0627 } TW_Param_Apache, *PTW_Param_Apache;
0628 
0629 /* Response queue */
0630 typedef union TAG_TW_Response_Queue {
0631     u32 response_id;
0632     u32 value;
0633 } TW_Response_Queue;
0634 
0635 /* Compatibility information structure */
0636 typedef struct TAG_TW_Compatibility_Info
0637 {
0638     char driver_version[32];
0639     unsigned short working_srl;
0640     unsigned short working_branch;
0641     unsigned short working_build;
0642     unsigned short driver_srl_high;
0643     unsigned short driver_branch_high;
0644     unsigned short driver_build_high;
0645     unsigned short driver_srl_low;
0646     unsigned short driver_branch_low;
0647     unsigned short driver_build_low;
0648     unsigned short fw_on_ctlr_srl;
0649     unsigned short fw_on_ctlr_branch;
0650     unsigned short fw_on_ctlr_build;
0651 } TW_Compatibility_Info;
0652 
0653 typedef struct TAG_TW_Device_Extension {
0654     u32         __iomem *base_addr;
0655     unsigned long       *generic_buffer_virt[TW_Q_LENGTH];
0656     dma_addr_t      generic_buffer_phys[TW_Q_LENGTH];
0657     TW_Command_Full     *command_packet_virt[TW_Q_LENGTH];
0658     dma_addr_t      command_packet_phys[TW_Q_LENGTH];
0659     struct pci_dev      *tw_pci_dev;
0660     struct scsi_cmnd    *srb[TW_Q_LENGTH];
0661     unsigned char       free_queue[TW_Q_LENGTH];
0662     unsigned char       free_head;
0663     unsigned char       free_tail;
0664     unsigned char       pending_queue[TW_Q_LENGTH];
0665     unsigned char       pending_head;
0666     unsigned char       pending_tail;
0667     int         state[TW_Q_LENGTH];
0668     unsigned int        posted_request_count;
0669     unsigned int        max_posted_request_count;
0670     unsigned int        pending_request_count;
0671     unsigned int        max_pending_request_count;
0672     unsigned int        max_sgl_entries;
0673     unsigned int        sgl_entries;
0674     unsigned int        num_resets;
0675     unsigned int        sector_count;
0676     unsigned int        max_sector_count;
0677     unsigned int        aen_count;
0678     struct Scsi_Host    *host;
0679     long            flags;
0680     int         reset_print;
0681     TW_Event        *event_queue[TW_Q_LENGTH];
0682     unsigned char       error_index;
0683     unsigned char       event_queue_wrapped;
0684     unsigned int        error_sequence_id;
0685     int         ioctl_sem_lock;
0686     ktime_t         ioctl_time;
0687     int         chrdev_request_id;
0688     wait_queue_head_t   ioctl_wqueue;
0689     struct mutex        ioctl_lock;
0690     char            aen_clobber;
0691     TW_Compatibility_Info   tw_compat_info;
0692 } TW_Device_Extension;
0693 
0694 #endif /* _3W_9XXX_H */
0695