406 lines · c
1/*2 3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux.3 4 Written By: Adam Radford <aradford@gmail.com>5 6 Copyright (C) 2009 LSI Corporation.7 8 This program is free software; you can redistribute it and/or modify9 it under the terms of the GNU General Public License as published by10 the Free Software Foundation; version 2 of the License.11 12 This program is distributed in the hope that it will be useful,13 but WITHOUT ANY WARRANTY; without even the implied warranty of14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the15 GNU General Public License for more details.16 17 NO WARRANTY18 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR19 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT20 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is22 solely responsible for determining the appropriateness of using and23 distributing the Program and assumes all risks associated with its24 exercise of rights under this Agreement, including but not limited to25 the risks and costs of program errors, damage to or loss of data,26 programs or equipment, and unavailability or interruption of operations.27 28 DISCLAIMER OF LIABILITY29 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY30 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL31 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR33 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE34 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED35 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES36 37 You should have received a copy of the GNU General Public License38 along with this program; if not, write to the Free Software39 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA40 41 Bugs/Comments/Suggestions should be mailed to:42 aradford@gmail.com43*/44 45#ifndef _3W_SAS_H46#define _3W_SAS_H47 48/* AEN severity table */49static char *twl_aen_severity_table[] =50{51 "None", "ERROR", "WARNING", "INFO", "DEBUG", NULL52};53 54/* Liberator register offsets */55#define TWL_STATUS 0x0 /* Status */56#define TWL_HIBDB 0x20 /* Inbound doorbell */57#define TWL_HISTAT 0x30 /* Host interrupt status */58#define TWL_HIMASK 0x34 /* Host interrupt mask */59#define TWL_HOBDB 0x9C /* Outbound doorbell */60#define TWL_HOBDBC 0xA0 /* Outbound doorbell clear */61#define TWL_SCRPD3 0xBC /* Scratchpad */62#define TWL_HIBQPL 0xC0 /* Host inbound Q low */63#define TWL_HIBQPH 0xC4 /* Host inbound Q high */64#define TWL_HOBQPL 0xC8 /* Host outbound Q low */65#define TWL_HOBQPH 0xCC /* Host outbound Q high */66#define TWL_HISTATUS_VALID_INTERRUPT 0xC67#define TWL_HISTATUS_ATTENTION_INTERRUPT 0x468#define TWL_HISTATUS_RESPONSE_INTERRUPT 0x869#define TWL_STATUS_OVERRUN_SUBMIT 0x200070#define TWL_ISSUE_SOFT_RESET 0x10071#define TWL_CONTROLLER_READY 0x200072#define TWL_DOORBELL_CONTROLLER_ERROR 0x20000073#define TWL_DOORBELL_ATTENTION_INTERRUPT 0x4000074#define TWL_PULL_MODE 0x175 76/* Command packet opcodes used by the driver */77#define TW_OP_INIT_CONNECTION 0x178#define TW_OP_GET_PARAM 0x1279#define TW_OP_SET_PARAM 0x1380#define TW_OP_EXECUTE_SCSI 0x1081 82/* Asynchronous Event Notification (AEN) codes used by the driver */83#define TW_AEN_QUEUE_EMPTY 0x000084#define TW_AEN_SOFT_RESET 0x000185#define TW_AEN_SYNC_TIME_WITH_HOST 0x03186#define TW_AEN_SEVERITY_ERROR 0x187#define TW_AEN_SEVERITY_DEBUG 0x488#define TW_AEN_NOT_RETRIEVED 0x189 90/* Command state defines */91#define TW_S_INITIAL 0x1 /* Initial state */92#define TW_S_STARTED 0x2 /* Id in use */93#define TW_S_POSTED 0x4 /* Posted to the controller */94#define TW_S_COMPLETED 0x8 /* Completed by isr */95#define TW_S_FINISHED 0x10 /* I/O completely done */96 97/* Compatibility defines */98#define TW_9750_ARCH_ID 1099#define TW_CURRENT_DRIVER_SRL 40100#define TW_CURRENT_DRIVER_BUILD 0101#define TW_CURRENT_DRIVER_BRANCH 0102 103/* Misc defines */104#define TW_SECTOR_SIZE 512105#define TW_MAX_UNITS 32106#define TW_INIT_MESSAGE_CREDITS 0x100107#define TW_INIT_COMMAND_PACKET_SIZE 0x3108#define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6109#define TW_EXTENDED_INIT_CONNECT 0x2110#define TW_BASE_FW_SRL 24111#define TW_BASE_FW_BRANCH 0112#define TW_BASE_FW_BUILD 1113#define TW_Q_LENGTH 256114#define TW_Q_START 0115#define TW_MAX_SLOT 32116#define TW_MAX_RESET_TRIES 2117#define TW_MAX_CMDS_PER_LUN 254118#define TW_MAX_AEN_DRAIN 255119#define TW_IN_RESET 2120#define TW_USING_MSI 3121#define TW_IN_ATTENTION_LOOP 4122#define TW_MAX_SECTORS 256123#define TW_MAX_CDB_LEN 16124#define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */125#define TW_IOCTL_CHRDEV_FREE -1126#define TW_COMMAND_OFFSET 128 /* 128 bytes */127#define TW_VERSION_TABLE 0x0402128#define TW_TIMEKEEP_TABLE 0x040A129#define TW_INFORMATION_TABLE 0x0403130#define TW_PARAM_FWVER 3131#define TW_PARAM_FWVER_LENGTH 16132#define TW_PARAM_BIOSVER 4133#define TW_PARAM_BIOSVER_LENGTH 16134#define TW_PARAM_MODEL 8135#define TW_PARAM_MODEL_LENGTH 16136#define TW_PARAM_PHY_SUMMARY_TABLE 1137#define TW_PARAM_PHYCOUNT 2138#define TW_PARAM_PHYCOUNT_LENGTH 1139#define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 // Used by smartmontools140#define TW_ALLOCATION_LENGTH 128141#define TW_SENSE_DATA_LENGTH 18142#define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x10a143#define TW_ERROR_INVALID_FIELD_IN_CDB 0x10d144#define TW_ERROR_UNIT_OFFLINE 0x128145#define TW_MESSAGE_SOURCE_CONTROLLER_ERROR 3146#define TW_MESSAGE_SOURCE_CONTROLLER_EVENT 4147#define TW_DRIVER 6148#ifndef PCI_DEVICE_ID_3WARE_9750149#define PCI_DEVICE_ID_3WARE_9750 0x1010150#endif151 152/* Bitmask macros to eliminate bitfields */153 154/* opcode: 5, reserved: 3 */155#define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f))156#define TW_OP_OUT(x) (x & 0x1f)157 158/* opcode: 5, sgloffset: 3 */159#define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f))160#define TW_SGL_OUT(x) ((x >> 5) & 0x7)161 162/* severity: 3, reserved: 5 */163#define TW_SEV_OUT(x) (x & 0x7)164 165/* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */166#define TW_RESID_OUT(x) ((x >> 16) & 0xffff)167#define TW_NOTMFA_OUT(x) (x & 0x1)168 169/* request_id: 12, lun: 4 */170#define TW_REQ_LUN_IN(lun, request_id) \171 (((lun << 12) & 0xf000) | (request_id & 0xfff))172#define TW_LUN_OUT(lun) ((lun >> 12) & 0xf)173 174/* Register access macros */175#define TWL_STATUS_REG_ADDR(x) \176 ((unsigned char __iomem *)x->base_addr + TWL_STATUS)177#define TWL_HOBQPL_REG_ADDR(x) \178 ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL)179#define TWL_HOBQPH_REG_ADDR(x) \180 ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH)181#define TWL_HOBDB_REG_ADDR(x) \182 ((unsigned char __iomem *)x->base_addr + TWL_HOBDB)183#define TWL_HOBDBC_REG_ADDR(x) \184 ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC)185#define TWL_HIMASK_REG_ADDR(x) \186 ((unsigned char __iomem *)x->base_addr + TWL_HIMASK)187#define TWL_HISTAT_REG_ADDR(x) \188 ((unsigned char __iomem *)x->base_addr + TWL_HISTAT)189#define TWL_HIBQPH_REG_ADDR(x) \190 ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH)191#define TWL_HIBQPL_REG_ADDR(x) \192 ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL)193#define TWL_HIBDB_REG_ADDR(x) \194 ((unsigned char __iomem *)x->base_addr + TWL_HIBDB)195#define TWL_SCRPD3_REG_ADDR(x) \196 ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3)197#define TWL_MASK_INTERRUPTS(x) \198 (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev)))199#define TWL_UNMASK_INTERRUPTS(x) \200 (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev)))201#define TWL_CLEAR_DB_INTERRUPT(x) \202 (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev)))203#define TWL_SOFT_RESET(x) \204 (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev)))205 206/* Macros */207#define TW_PRINTK(h,a,b,c) { \208if (h) \209printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \210else \211printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \212}213#define TW_MAX_LUNS 16214#define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4)215#define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92)216#define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94)217#define TW_PADDING_LENGTH_LIBERATOR 136218#define TW_PADDING_LENGTH_LIBERATOR_OLD 132219#define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x))220 221#pragma pack(1)222 223/* SGL entry */224typedef struct TAG_TW_SG_Entry_ISO {225 dma_addr_t address;226 dma_addr_t length;227} TW_SG_Entry_ISO;228 229/* Old Command Packet with ISO SGL */230typedef struct TW_Command {231 unsigned char opcode__sgloffset;232 unsigned char size;233 unsigned char request_id;234 unsigned char unit__hostid;235 /* Second DWORD */236 unsigned char status;237 unsigned char flags;238 union {239 unsigned short block_count;240 unsigned short parameter_count;241 } byte6_offset;242 union {243 struct {244 u32 lba;245 TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];246 unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD];247 } io;248 struct {249 TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD];250 u32 padding;251 unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD];252 } param;253 } byte8_offset;254} TW_Command;255 256/* New Command Packet with ISO SGL */257typedef struct TAG_TW_Command_Apache {258 unsigned char opcode__reserved;259 unsigned char unit;260 unsigned short request_id__lunl;261 unsigned char status;262 unsigned char sgl_offset;263 unsigned short sgl_entries__lunh;264 unsigned char cdb[16];265 TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH];266 unsigned char padding[TW_PADDING_LENGTH_LIBERATOR];267} TW_Command_Apache;268 269/* New command packet header */270typedef struct TAG_TW_Command_Apache_Header {271 unsigned char sense_data[TW_SENSE_DATA_LENGTH];272 struct {273 char reserved[4];274 unsigned short error;275 unsigned char padding;276 unsigned char severity__reserved;277 } status_block;278 unsigned char err_specific_desc[98];279 struct {280 unsigned char size_header;281 unsigned short request_id;282 unsigned char size_sense;283 } header_desc;284} TW_Command_Apache_Header;285 286/* This struct is a union of the 2 command packets */287typedef struct TAG_TW_Command_Full {288 TW_Command_Apache_Header header;289 union {290 TW_Command oldcommand;291 TW_Command_Apache newcommand;292 } command;293} TW_Command_Full;294 295/* Initconnection structure */296typedef struct TAG_TW_Initconnect {297 unsigned char opcode__reserved;298 unsigned char size;299 unsigned char request_id;300 unsigned char res2;301 unsigned char status;302 unsigned char flags;303 unsigned short message_credits;304 u32 features;305 unsigned short fw_srl;306 unsigned short fw_arch_id;307 unsigned short fw_branch;308 unsigned short fw_build;309 u32 result;310} TW_Initconnect;311 312/* Event info structure */313typedef struct TAG_TW_Event314{315 unsigned int sequence_id;316 unsigned int time_stamp_sec;317 unsigned short aen_code;318 unsigned char severity;319 unsigned char retrieved;320 unsigned char repeat_count;321 unsigned char parameter_len;322 unsigned char parameter_data[98];323} TW_Event;324 325typedef struct TAG_TW_Ioctl_Driver_Command {326 unsigned int control_code;327 unsigned int status;328 unsigned int unique_id;329 unsigned int sequence_id;330 unsigned int os_specific;331 unsigned int buffer_length;332} TW_Ioctl_Driver_Command;333 334typedef struct TAG_TW_Ioctl_Apache {335 TW_Ioctl_Driver_Command driver_command;336 char padding[488];337 TW_Command_Full firmware_command;338 char data_buffer[];339} TW_Ioctl_Buf_Apache;340 341/* GetParam descriptor */342typedef struct {343 unsigned short table_id;344 unsigned short parameter_id;345 unsigned short parameter_size_bytes;346 unsigned short actual_parameter_size_bytes;347 unsigned char data[];348} TW_Param_Apache;349 350/* Compatibility information structure */351typedef struct TAG_TW_Compatibility_Info352{353 char driver_version[32];354 unsigned short working_srl;355 unsigned short working_branch;356 unsigned short working_build;357 unsigned short driver_srl_high;358 unsigned short driver_branch_high;359 unsigned short driver_build_high;360 unsigned short driver_srl_low;361 unsigned short driver_branch_low;362 unsigned short driver_build_low;363 unsigned short fw_on_ctlr_srl;364 unsigned short fw_on_ctlr_branch;365 unsigned short fw_on_ctlr_build;366} TW_Compatibility_Info;367 368#pragma pack()369 370typedef struct TAG_TW_Device_Extension {371 void __iomem *base_addr;372 unsigned long *generic_buffer_virt[TW_Q_LENGTH];373 dma_addr_t generic_buffer_phys[TW_Q_LENGTH];374 TW_Command_Full *command_packet_virt[TW_Q_LENGTH];375 dma_addr_t command_packet_phys[TW_Q_LENGTH];376 TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH];377 dma_addr_t sense_buffer_phys[TW_Q_LENGTH];378 struct pci_dev *tw_pci_dev;379 struct scsi_cmnd *srb[TW_Q_LENGTH];380 unsigned char free_queue[TW_Q_LENGTH];381 unsigned char free_head;382 unsigned char free_tail;383 int state[TW_Q_LENGTH];384 unsigned int posted_request_count;385 unsigned int max_posted_request_count;386 unsigned int max_sgl_entries;387 unsigned int sgl_entries;388 unsigned int num_resets;389 unsigned int sector_count;390 unsigned int max_sector_count;391 unsigned int aen_count;392 struct Scsi_Host *host;393 long flags;394 TW_Event *event_queue[TW_Q_LENGTH];395 unsigned char error_index;396 unsigned int error_sequence_id;397 int chrdev_request_id;398 wait_queue_head_t ioctl_wqueue;399 struct mutex ioctl_lock;400 TW_Compatibility_Info tw_compat_info;401 char online;402} TW_Device_Extension;403 404#endif /* _3W_SAS_H */405 406