1 /* 2 3w-sas.h -- LSI 3ware SAS/SATA-RAID Controller device driver for Linux. 3 4 Written By: Adam Radford <linuxraid@lsi.com> 5 6 Copyright (C) 2009 LSI Corporation. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 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 of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 NO WARRANTY 18 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 19 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 20 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 21 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 22 solely responsible for determining the appropriateness of using and 23 distributing the Program and assumes all risks associated with its 24 exercise of rights under this Agreement, including but not limited to 25 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 LIABILITY 29 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 30 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 32 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 34 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 35 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 36 37 You should have received a copy of the GNU General Public License 38 along with this program; if not, write to the Free Software 39 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 40 41 Bugs/Comments/Suggestions should be mailed to: 42 linuxraid@lsi.com 43 44 For more information, goto: 45 http://www.lsi.com 46 */ 47 48 #ifndef _3W_SAS_H 49 #define _3W_SAS_H 50 51 /* AEN severity table */ 52 static char *twl_aen_severity_table[] = 53 { 54 "None", "ERROR", "WARNING", "INFO", "DEBUG", NULL 55 }; 56 57 /* Liberator register offsets */ 58 #define TWL_STATUS 0x0 /* Status */ 59 #define TWL_HIBDB 0x20 /* Inbound doorbell */ 60 #define TWL_HISTAT 0x30 /* Host interrupt status */ 61 #define TWL_HIMASK 0x34 /* Host interrupt mask */ 62 #define TWL_HOBDB 0x9C /* Outbound doorbell */ 63 #define TWL_HOBDBC 0xA0 /* Outbound doorbell clear */ 64 #define TWL_SCRPD3 0xBC /* Scratchpad */ 65 #define TWL_HIBQPL 0xC0 /* Host inbound Q low */ 66 #define TWL_HIBQPH 0xC4 /* Host inbound Q high */ 67 #define TWL_HOBQPL 0xC8 /* Host outbound Q low */ 68 #define TWL_HOBQPH 0xCC /* Host outbound Q high */ 69 #define TWL_HISTATUS_VALID_INTERRUPT 0xC 70 #define TWL_HISTATUS_ATTENTION_INTERRUPT 0x4 71 #define TWL_HISTATUS_RESPONSE_INTERRUPT 0x8 72 #define TWL_STATUS_OVERRUN_SUBMIT 0x2000 73 #define TWL_ISSUE_SOFT_RESET 0x100 74 #define TWL_CONTROLLER_READY 0x2000 75 #define TWL_DOORBELL_CONTROLLER_ERROR 0x200000 76 #define TWL_DOORBELL_ATTENTION_INTERRUPT 0x40000 77 #define TWL_PULL_MODE 0x1 78 79 /* Command packet opcodes used by the driver */ 80 #define TW_OP_INIT_CONNECTION 0x1 81 #define TW_OP_GET_PARAM 0x12 82 #define TW_OP_SET_PARAM 0x13 83 #define TW_OP_EXECUTE_SCSI 0x10 84 85 /* Asynchronous Event Notification (AEN) codes used by the driver */ 86 #define TW_AEN_QUEUE_EMPTY 0x0000 87 #define TW_AEN_SOFT_RESET 0x0001 88 #define TW_AEN_SYNC_TIME_WITH_HOST 0x031 89 #define TW_AEN_SEVERITY_ERROR 0x1 90 #define TW_AEN_SEVERITY_DEBUG 0x4 91 #define TW_AEN_NOT_RETRIEVED 0x1 92 93 /* Command state defines */ 94 #define TW_S_INITIAL 0x1 /* Initial state */ 95 #define TW_S_STARTED 0x2 /* Id in use */ 96 #define TW_S_POSTED 0x4 /* Posted to the controller */ 97 #define TW_S_COMPLETED 0x8 /* Completed by isr */ 98 #define TW_S_FINISHED 0x10 /* I/O completely done */ 99 100 /* Compatibility defines */ 101 #define TW_9750_ARCH_ID 10 102 #define TW_CURRENT_DRIVER_SRL 40 103 #define TW_CURRENT_DRIVER_BUILD 0 104 #define TW_CURRENT_DRIVER_BRANCH 0 105 106 /* Misc defines */ 107 #define TW_SECTOR_SIZE 512 108 #define TW_MAX_UNITS 32 109 #define TW_INIT_MESSAGE_CREDITS 0x100 110 #define TW_INIT_COMMAND_PACKET_SIZE 0x3 111 #define TW_INIT_COMMAND_PACKET_SIZE_EXTENDED 0x6 112 #define TW_EXTENDED_INIT_CONNECT 0x2 113 #define TW_BASE_FW_SRL 24 114 #define TW_BASE_FW_BRANCH 0 115 #define TW_BASE_FW_BUILD 1 116 #define TW_Q_LENGTH 256 117 #define TW_Q_START 0 118 #define TW_MAX_SLOT 32 119 #define TW_MAX_RESET_TRIES 2 120 #define TW_MAX_CMDS_PER_LUN 254 121 #define TW_MAX_AEN_DRAIN 255 122 #define TW_IN_RESET 2 123 #define TW_USING_MSI 3 124 #define TW_IN_ATTENTION_LOOP 4 125 #define TW_MAX_SECTORS 256 126 #define TW_MAX_CDB_LEN 16 127 #define TW_IOCTL_CHRDEV_TIMEOUT 60 /* 60 seconds */ 128 #define TW_IOCTL_CHRDEV_FREE -1 129 #define TW_COMMAND_OFFSET 128 /* 128 bytes */ 130 #define TW_VERSION_TABLE 0x0402 131 #define TW_TIMEKEEP_TABLE 0x040A 132 #define TW_INFORMATION_TABLE 0x0403 133 #define TW_PARAM_FWVER 3 134 #define TW_PARAM_FWVER_LENGTH 16 135 #define TW_PARAM_BIOSVER 4 136 #define TW_PARAM_BIOSVER_LENGTH 16 137 #define TW_PARAM_MODEL 8 138 #define TW_PARAM_MODEL_LENGTH 16 139 #define TW_PARAM_PHY_SUMMARY_TABLE 1 140 #define TW_PARAM_PHYCOUNT 2 141 #define TW_PARAM_PHYCOUNT_LENGTH 1 142 #define TW_IOCTL_FIRMWARE_PASS_THROUGH 0x108 // Used by smartmontools 143 #define TW_ALLOCATION_LENGTH 128 144 #define TW_SENSE_DATA_LENGTH 18 145 #define TW_ERROR_LOGICAL_UNIT_NOT_SUPPORTED 0x10a 146 #define TW_ERROR_INVALID_FIELD_IN_CDB 0x10d 147 #define TW_ERROR_UNIT_OFFLINE 0x128 148 #define TW_MESSAGE_SOURCE_CONTROLLER_ERROR 3 149 #define TW_MESSAGE_SOURCE_CONTROLLER_EVENT 4 150 #define TW_DRIVER 6 151 #ifndef PCI_DEVICE_ID_3WARE_9750 152 #define PCI_DEVICE_ID_3WARE_9750 0x1010 153 #endif 154 155 /* Bitmask macros to eliminate bitfields */ 156 157 /* opcode: 5, reserved: 3 */ 158 #define TW_OPRES_IN(x,y) ((x << 5) | (y & 0x1f)) 159 #define TW_OP_OUT(x) (x & 0x1f) 160 161 /* opcode: 5, sgloffset: 3 */ 162 #define TW_OPSGL_IN(x,y) ((x << 5) | (y & 0x1f)) 163 #define TW_SGL_OUT(x) ((x >> 5) & 0x7) 164 165 /* severity: 3, reserved: 5 */ 166 #define TW_SEV_OUT(x) (x & 0x7) 167 168 /* not_mfa: 1, reserved: 7, status: 8, request_id: 16 */ 169 #define TW_RESID_OUT(x) ((x >> 16) & 0xffff) 170 #define TW_NOTMFA_OUT(x) (x & 0x1) 171 172 /* request_id: 12, lun: 4 */ 173 #define TW_REQ_LUN_IN(lun, request_id) (((lun << 12) & 0xf000) | (request_id & 0xfff)) 174 #define TW_LUN_OUT(lun) ((lun >> 12) & 0xf) 175 176 /* Register access macros */ 177 #define TWL_STATUS_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_STATUS) 178 #define TWL_HOBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPL) 179 #define TWL_HOBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBQPH) 180 #define TWL_HOBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDB) 181 #define TWL_HOBDBC_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HOBDBC) 182 #define TWL_HIMASK_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIMASK) 183 #define TWL_HISTAT_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HISTAT) 184 #define TWL_HIBQPH_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPH) 185 #define TWL_HIBQPL_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBQPL) 186 #define TWL_HIBDB_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_HIBDB) 187 #define TWL_SCRPD3_REG_ADDR(x) ((unsigned char __iomem *)x->base_addr + TWL_SCRPD3) 188 #define TWL_MASK_INTERRUPTS(x) (writel(~0, TWL_HIMASK_REG_ADDR(tw_dev))) 189 #define TWL_UNMASK_INTERRUPTS(x) (writel(~TWL_HISTATUS_VALID_INTERRUPT, TWL_HIMASK_REG_ADDR(tw_dev))) 190 #define TWL_CLEAR_DB_INTERRUPT(x) (writel(~0, TWL_HOBDBC_REG_ADDR(tw_dev))) 191 #define TWL_SOFT_RESET(x) (writel(TWL_ISSUE_SOFT_RESET, TWL_HIBDB_REG_ADDR(tw_dev))) 192 193 /* Macros */ 194 #define TW_PRINTK(h,a,b,c) { \ 195 if (h) \ 196 printk(KERN_WARNING "3w-sas: scsi%d: ERROR: (0x%02X:0x%04X): %s.\n",h->host_no,a,b,c); \ 197 else \ 198 printk(KERN_WARNING "3w-sas: ERROR: (0x%02X:0x%04X): %s.\n",a,b,c); \ 199 } 200 #define TW_MAX_LUNS 16 201 #define TW_COMMAND_SIZE (sizeof(dma_addr_t) > 4 ? 6 : 4) 202 #define TW_LIBERATOR_MAX_SGL_LENGTH (sizeof(dma_addr_t) > 4 ? 46 : 92) 203 #define TW_LIBERATOR_MAX_SGL_LENGTH_OLD (sizeof(dma_addr_t) > 4 ? 47 : 94) 204 #define TW_PADDING_LENGTH_LIBERATOR 136 205 #define TW_PADDING_LENGTH_LIBERATOR_OLD 132 206 #define TW_CPU_TO_SGL(x) (sizeof(dma_addr_t) > 4 ? cpu_to_le64(x) : cpu_to_le32(x)) 207 208 #pragma pack(1) 209 210 /* SGL entry */ 211 typedef struct TAG_TW_SG_Entry_ISO { 212 dma_addr_t address; 213 dma_addr_t length; 214 } TW_SG_Entry_ISO; 215 216 /* Old Command Packet with ISO SGL */ 217 typedef struct TW_Command { 218 unsigned char opcode__sgloffset; 219 unsigned char size; 220 unsigned char request_id; 221 unsigned char unit__hostid; 222 /* Second DWORD */ 223 unsigned char status; 224 unsigned char flags; 225 union { 226 unsigned short block_count; 227 unsigned short parameter_count; 228 } byte6_offset; 229 union { 230 struct { 231 u32 lba; 232 TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD]; 233 unsigned char padding[TW_PADDING_LENGTH_LIBERATOR_OLD]; 234 } io; 235 struct { 236 TW_SG_Entry_ISO sgl[TW_LIBERATOR_MAX_SGL_LENGTH_OLD]; 237 u32 padding; 238 unsigned char padding2[TW_PADDING_LENGTH_LIBERATOR_OLD]; 239 } param; 240 } byte8_offset; 241 } TW_Command; 242 243 /* New Command Packet with ISO SGL */ 244 typedef struct TAG_TW_Command_Apache { 245 unsigned char opcode__reserved; 246 unsigned char unit; 247 unsigned short request_id__lunl; 248 unsigned char status; 249 unsigned char sgl_offset; 250 unsigned short sgl_entries__lunh; 251 unsigned char cdb[16]; 252 TW_SG_Entry_ISO sg_list[TW_LIBERATOR_MAX_SGL_LENGTH]; 253 unsigned char padding[TW_PADDING_LENGTH_LIBERATOR]; 254 } TW_Command_Apache; 255 256 /* New command packet header */ 257 typedef struct TAG_TW_Command_Apache_Header { 258 unsigned char sense_data[TW_SENSE_DATA_LENGTH]; 259 struct { 260 char reserved[4]; 261 unsigned short error; 262 unsigned char padding; 263 unsigned char severity__reserved; 264 } status_block; 265 unsigned char err_specific_desc[98]; 266 struct { 267 unsigned char size_header; 268 unsigned short request_id; 269 unsigned char size_sense; 270 } header_desc; 271 } TW_Command_Apache_Header; 272 273 /* This struct is a union of the 2 command packets */ 274 typedef struct TAG_TW_Command_Full { 275 TW_Command_Apache_Header header; 276 union { 277 TW_Command oldcommand; 278 TW_Command_Apache newcommand; 279 } command; 280 } TW_Command_Full; 281 282 /* Initconnection structure */ 283 typedef struct TAG_TW_Initconnect { 284 unsigned char opcode__reserved; 285 unsigned char size; 286 unsigned char request_id; 287 unsigned char res2; 288 unsigned char status; 289 unsigned char flags; 290 unsigned short message_credits; 291 u32 features; 292 unsigned short fw_srl; 293 unsigned short fw_arch_id; 294 unsigned short fw_branch; 295 unsigned short fw_build; 296 u32 result; 297 } TW_Initconnect; 298 299 /* Event info structure */ 300 typedef struct TAG_TW_Event 301 { 302 unsigned int sequence_id; 303 unsigned int time_stamp_sec; 304 unsigned short aen_code; 305 unsigned char severity; 306 unsigned char retrieved; 307 unsigned char repeat_count; 308 unsigned char parameter_len; 309 unsigned char parameter_data[98]; 310 } TW_Event; 311 312 typedef struct TAG_TW_Ioctl_Driver_Command { 313 unsigned int control_code; 314 unsigned int status; 315 unsigned int unique_id; 316 unsigned int sequence_id; 317 unsigned int os_specific; 318 unsigned int buffer_length; 319 } TW_Ioctl_Driver_Command; 320 321 typedef struct TAG_TW_Ioctl_Apache { 322 TW_Ioctl_Driver_Command driver_command; 323 char padding[488]; 324 TW_Command_Full firmware_command; 325 char data_buffer[1]; 326 } TW_Ioctl_Buf_Apache; 327 328 /* GetParam descriptor */ 329 typedef struct { 330 unsigned short table_id; 331 unsigned short parameter_id; 332 unsigned short parameter_size_bytes; 333 unsigned short actual_parameter_size_bytes; 334 unsigned char data[1]; 335 } TW_Param_Apache; 336 337 /* Compatibility information structure */ 338 typedef struct TAG_TW_Compatibility_Info 339 { 340 char driver_version[32]; 341 unsigned short working_srl; 342 unsigned short working_branch; 343 unsigned short working_build; 344 unsigned short driver_srl_high; 345 unsigned short driver_branch_high; 346 unsigned short driver_build_high; 347 unsigned short driver_srl_low; 348 unsigned short driver_branch_low; 349 unsigned short driver_build_low; 350 unsigned short fw_on_ctlr_srl; 351 unsigned short fw_on_ctlr_branch; 352 unsigned short fw_on_ctlr_build; 353 } TW_Compatibility_Info; 354 355 #pragma pack() 356 357 typedef struct TAG_TW_Device_Extension { 358 void __iomem *base_addr; 359 unsigned long *generic_buffer_virt[TW_Q_LENGTH]; 360 dma_addr_t generic_buffer_phys[TW_Q_LENGTH]; 361 TW_Command_Full *command_packet_virt[TW_Q_LENGTH]; 362 dma_addr_t command_packet_phys[TW_Q_LENGTH]; 363 TW_Command_Apache_Header *sense_buffer_virt[TW_Q_LENGTH]; 364 dma_addr_t sense_buffer_phys[TW_Q_LENGTH]; 365 struct pci_dev *tw_pci_dev; 366 struct scsi_cmnd *srb[TW_Q_LENGTH]; 367 unsigned char free_queue[TW_Q_LENGTH]; 368 unsigned char free_head; 369 unsigned char free_tail; 370 int state[TW_Q_LENGTH]; 371 unsigned int posted_request_count; 372 unsigned int max_posted_request_count; 373 unsigned int max_sgl_entries; 374 unsigned int sgl_entries; 375 unsigned int num_resets; 376 unsigned int sector_count; 377 unsigned int max_sector_count; 378 unsigned int aen_count; 379 struct Scsi_Host *host; 380 long flags; 381 TW_Event *event_queue[TW_Q_LENGTH]; 382 unsigned char error_index; 383 unsigned int error_sequence_id; 384 int chrdev_request_id; 385 wait_queue_head_t ioctl_wqueue; 386 struct mutex ioctl_lock; 387 TW_Compatibility_Info tw_compat_info; 388 char online; 389 } TW_Device_Extension; 390 391 #endif /* _3W_SAS_H */ 392 393