├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── mpt.h ├── mpt ├── mpi │ ├── mpi2.h │ ├── mpi2_cnfg.h │ ├── mpi2_init.h │ ├── mpi2_ioc.h │ ├── mpi2_raid.h │ ├── mpi2_sas.h │ ├── mpi2_tool.h │ └── mpi2_type.h ├── mpt2sas_ctl.h └── mpt3sas_ctl.h ├── mptevents.c ├── mptevents_offline.c └── mptparser.c /.gitignore: -------------------------------------------------------------------------------- 1 | mptevents 2 | mptevents_offline 3 | *.o 4 | .*.swp 5 | .gdb_history 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | script: make 4 | 5 | compiler: 6 | - gcc 7 | - clang 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Baruch Even 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION=1.3 2 | CFLAGS=-O0 -g -Wall -Impt -DVERSION=\"${VERSION}\" 3 | 4 | all: mptevents mptevents_offline 5 | mptevents: mptevents.o mptparser.o | Makefile 6 | mptevents_offline: mptevents_offline.o mptparser.o | Makefile 7 | mptevents.o: mptevents.c | Makefile 8 | mptparser.o: mptparser.c | Makefile 9 | tags: mptevents.c $(wildcard mpt/*.h) $(wildcard mpt/mpi/*.h) 10 | ctags $^ 11 | clean: 12 | -rm -f mptevents mptevents_offline *.o tags 13 | 14 | .PHONY: all clean 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mptevents 2 | ========= 3 | 4 | [![Build Status](https://travis-ci.org/baruch/mptevents.svg?branch=master)](https://travis-ci.org/baruch/mptevents) 5 | 6 | The MPT drivers from LSI have an event reporting mechanism built in to the 7 | driver which enables to get a sneak peak into what happens in the SAS network 8 | at a level below that of the OS itself and can provide insights when debugging 9 | SAS issues. 10 | 11 | mptevents is a small daemon intended to expose that information by reporting it 12 | all to syslog. 13 | 14 | How to Use 15 | ---------- 16 | 17 | Just make sure to run this daemon at system startup or when debugging is 18 | needed, give it the device name to open such as /dev/mpt2ctl or /dev/mpt3ctl 19 | and it will send syslog messages. 20 | 21 | This daemon will try to auto-detect each supported host in /sys/class/scsi_host. 22 | Any unsupported host (e.g. ahci) will be ignored. 23 | 24 | If you give it no arguments it will try to auto-detect the control device and 25 | use that if it finds only one. If more than one is available you'll need to 26 | decide which one to use. 27 | 28 | Understanding the logs 29 | ---------------------- 30 | 31 | The logs generated will look something like the following, I will add inline comments to explain some of the things that can be seen here. 32 | 33 | SAS Device Status Change: ioc=1 context=2 tag=ffff rc=8(INTERNAL_DEVICE_RESET) port=0 asc=00 ascq=00 handle=000a reserved2=0 SASAddress=5000cca02b0458ba 34 | 35 | Here the device was reset for some reason, the SAS HBA most likely lost contact with the device and issued an internal reset to clear out all associated IOs against the device. We can see the SAS address and the handle both of which identify the device. 36 | 37 | SAS Device Status Change: ioc=1 context=3 tag=ffff rc=14(COMPLETED_INTERNAL_DEV_RESET) port=0 asc=00 ascq=00 handle=000a reserved2=0 SASAddress=5000cca02b0458ba 38 | 39 | Here the reset was completed, there were no pending IOs to abort so things were quick (syslog output will provide timestamps as well, at least from the time the event was received by mptevents). 40 | 41 | SAS Discovery: context=12 flags=01(IN_PROGRESS) reason=1(STARTED) physical_port=0 discovery_status=0() reserved1=0 42 | SAS Device Status Change: ioc=1 context=13 tag=ffff rc=8(INTERNAL_DEVICE_RESET) port=0 asc=00 ascq=00 handle=000a reserved2=0 SASAddress=5000cca02b0458ba 43 | SAS Topology Change List: context=14 enclosure_handle=2 expander_dev_handle=9 num_phys=37 num_entries=1 start_phy_num=11 exp_status=3(RESPONDING) physical_port=0 reserved1=0 reserved2=0 44 | SAS Topology Change List Entry (1/1): attached_dev_handle=a link_rate=a(prev=RATE_6_0,next=UNKNOWN_LINK_RATE) phy_status=5(DELAY_NOT_RESPONDING) 45 | SAS Device Status Change: ioc=1 context=15 tag=ffff rc=14(COMPLETED_INTERNAL_DEV_RESET) port=0 asc=00 ascq=00 handle=000a reserved2=0 SASAddress=5000cca02b0458ba 46 | SAS Discovery: context=16 flags=00(IN_PROGRESS) reason=2(COMPLETED) physical_port=0 discovery_status=0() reserved1=0 47 | 48 | This shows a typical disk dropping from the SAS network, there is a "SAS Discovery" starting first, the information about the device is cleared and we also get a "SAS Topology Change List" that shows a single device switching from 6Gbps to unknown which means there is no device present anymore. 49 | 50 | SAS Discovery: context=17 flags=01(IN_PROGRESS) reason=1(STARTED) physical_port=0 discovery_status=0() reserved1=0 51 | SAS Topology Change List: context=18 enclosure_handle=2 expander_dev_handle=9 num_phys=37 num_entries=1 start_phy_num=11 exp_status=3(RESPONDING) physical_port=0 reserved1=0 reserved2=0 52 | SAS Topology Change List Entry (1/1): attached_dev_handle=a link_rate=0(prev=UNKNOWN_LINK_RATE,next=UNKNOWN_LINK_RATE) phy_status=2(DELAY_NOT_RESPONDING) 53 | SAS Discovery: context=19 flags=02(DEVICE_CHANGE) reason=2(COMPLETED) physical_port=0 discovery_status=0() reserved1=0 54 | SAS Discovery: context=20 flags=01(IN_PROGRESS) reason=1(STARTED) physical_port=0 discovery_status=0() reserved1=0 55 | SAS Discovery: context=21 flags=02(DEVICE_CHANGE) reason=2(COMPLETED) physical_port=0 discovery_status=0() reserved1=0 56 | SAS Topology Change List: context=22 enclosure_handle=2 expander_dev_handle=9 num_phys=37 num_entries=1 start_phy_num=11 exp_status=3(RESPONDING) physical_port=0 reserved1=0 reserved2=0 57 | SAS Topology Change List Entry (1/1): attached_dev_handle=a link_rate=a0(prev=UNKNOWN_LINK_RATE,next=RATE_6_0) phy_status=1(DELAY_NOT_RESPONDING) 58 | 59 | The above now shows how a device joins, again a SAS discovery a topology change list showing a device (weirdly with no new speed, could be associated with a fast removal and reinsertion causing the DELAY\_NOT\_RESPONDING state. In the second discovery we already get the device joining in. 60 | 61 | Support 62 | ------- 63 | 64 | Since the tool is quite obscure and requires understanding of the SAS/SATA protocol and the way things behave at a very low level I'm also happy to give a helping hand by looking at debug logs and trying to explain them. I'm also doing this for my own benefit, while I saw plenty of such traces debugging SAS/SATA issues I'm always interested in seeing more of these. My email is provided below, feel free to contact me with your problems and I'd do my best to help. I cannot guarantee anything besides a sincere attempt to debug such issues. 65 | 66 | License 67 | ------- 68 | 69 | My code is licensed under the MIT license (see LICENSE file). The files under 70 | the mpt directory are taken verbatim from the Linux kernel and are thus 71 | licensed under the GPLv2. 72 | 73 | Author 74 | ------ 75 | 76 | Baruch Even 77 | -------------------------------------------------------------------------------- /mpt.h: -------------------------------------------------------------------------------- 1 | #ifndef MPTEVENTS_MPT_H 2 | #define MPTEVENTS_MPT_H 3 | 4 | #include 5 | 6 | typedef uint8_t u8; 7 | typedef uint16_t __le16; 8 | typedef uint32_t __le32; 9 | typedef uint64_t __le64; 10 | 11 | #define __user 12 | 13 | #include "mpi/mpi2_type.h" 14 | #include "mpi/mpi2.h" 15 | #include "mpi/mpi2_cnfg.h" 16 | #include "mpi/mpi2_ioc.h" 17 | #include "mpt2sas_ctl.h" 18 | #include "mpt3sas_ctl.h" 19 | 20 | #define MPT_EVENTS_LOG "/var/log/mptevents.log" 21 | 22 | struct mpt_events { 23 | struct mpt2_ioctl_header hdr; 24 | struct MPT2_IOCTL_EVENTS event_data[MPT2SAS_CTL_EVENT_LOG_SIZE]; 25 | }; 26 | 27 | void dump_all_events(struct mpt_events *events, uint32_t *highest_context, int first_read); 28 | 29 | extern void (*my_syslog)(int priority, const char *format, ...); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /mpt/mpi/mpi2.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2014 LSI Corporation. 3 | * 4 | * 5 | * Name: mpi2.h 6 | * Title: MPI Message independent structures and definitions 7 | * including System Interface Register Set and 8 | * scatter/gather formats. 9 | * Creation Date: June 21, 2006 10 | * 11 | * mpi2.h Version: 02.00.35 12 | * 13 | * Version History 14 | * --------------- 15 | * 16 | * Date Version Description 17 | * -------- -------- ------------------------------------------------------ 18 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. 19 | * 06-04-07 02.00.01 Bumped MPI2_HEADER_VERSION_UNIT. 20 | * 06-26-07 02.00.02 Bumped MPI2_HEADER_VERSION_UNIT. 21 | * 08-31-07 02.00.03 Bumped MPI2_HEADER_VERSION_UNIT. 22 | * Moved ReplyPostHostIndex register to offset 0x6C of the 23 | * MPI2_SYSTEM_INTERFACE_REGS and modified the define for 24 | * MPI2_REPLY_POST_HOST_INDEX_OFFSET. 25 | * Added union of request descriptors. 26 | * Added union of reply descriptors. 27 | * 10-31-07 02.00.04 Bumped MPI2_HEADER_VERSION_UNIT. 28 | * Added define for MPI2_VERSION_02_00. 29 | * Fixed the size of the FunctionDependent5 field in the 30 | * MPI2_DEFAULT_REPLY structure. 31 | * 12-18-07 02.00.05 Bumped MPI2_HEADER_VERSION_UNIT. 32 | * Removed the MPI-defined Fault Codes and extended the 33 | * product specific codes up to 0xEFFF. 34 | * Added a sixth key value for the WriteSequence register 35 | * and changed the flush value to 0x0. 36 | * Added message function codes for Diagnostic Buffer Post 37 | * and Diagnsotic Release. 38 | * New IOCStatus define: MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED 39 | * Moved MPI2_VERSION_UNION from mpi2_ioc.h. 40 | * 02-29-08 02.00.06 Bumped MPI2_HEADER_VERSION_UNIT. 41 | * 03-03-08 02.00.07 Bumped MPI2_HEADER_VERSION_UNIT. 42 | * 05-21-08 02.00.08 Bumped MPI2_HEADER_VERSION_UNIT. 43 | * Added #defines for marking a reply descriptor as unused. 44 | * 06-27-08 02.00.09 Bumped MPI2_HEADER_VERSION_UNIT. 45 | * 10-02-08 02.00.10 Bumped MPI2_HEADER_VERSION_UNIT. 46 | * Moved LUN field defines from mpi2_init.h. 47 | * 01-19-09 02.00.11 Bumped MPI2_HEADER_VERSION_UNIT. 48 | * 05-06-09 02.00.12 Bumped MPI2_HEADER_VERSION_UNIT. 49 | * In all request and reply descriptors, replaced VF_ID 50 | * field with MSIxIndex field. 51 | * Removed DevHandle field from 52 | * MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR and made those 53 | * bytes reserved. 54 | * Added RAID Accelerator functionality. 55 | * 07-30-09 02.00.13 Bumped MPI2_HEADER_VERSION_UNIT. 56 | * 10-28-09 02.00.14 Bumped MPI2_HEADER_VERSION_UNIT. 57 | * Added MSI-x index mask and shift for Reply Post Host 58 | * Index register. 59 | * Added function code for Host Based Discovery Action. 60 | * 02-10-10 02.00.15 Bumped MPI2_HEADER_VERSION_UNIT. 61 | * Added define for MPI2_FUNCTION_PWR_MGMT_CONTROL. 62 | * Added defines for product-specific range of message 63 | * function codes, 0xF0 to 0xFF. 64 | * 05-12-10 02.00.16 Bumped MPI2_HEADER_VERSION_UNIT. 65 | * Added alternative defines for the SGE Direction bit. 66 | * 08-11-10 02.00.17 Bumped MPI2_HEADER_VERSION_UNIT. 67 | * 11-10-10 02.00.18 Bumped MPI2_HEADER_VERSION_UNIT. 68 | * Added MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR define. 69 | * 02-23-11 02.00.19 Bumped MPI2_HEADER_VERSION_UNIT. 70 | * Added MPI2_FUNCTION_SEND_HOST_MESSAGE. 71 | * 03-09-11 02.00.20 Bumped MPI2_HEADER_VERSION_UNIT. 72 | * 05-25-11 02.00.21 Bumped MPI2_HEADER_VERSION_UNIT. 73 | * 08-24-11 02.00.22 Bumped MPI2_HEADER_VERSION_UNIT. 74 | * 11-18-11 02.00.23 Bumped MPI2_HEADER_VERSION_UNIT. 75 | * 02-06-12 02.00.24 Bumped MPI2_HEADER_VERSION_UNIT. 76 | * 03-29-12 02.00.25 Bumped MPI2_HEADER_VERSION_UNIT. 77 | * Added Hard Reset delay timings. 78 | * 07-10-12 02.00.26 Bumped MPI2_HEADER_VERSION_UNIT. 79 | * 07-26-12 02.00.27 Bumped MPI2_HEADER_VERSION_UNIT. 80 | * 11-27-12 02.00.28 Bumped MPI2_HEADER_VERSION_UNIT. 81 | * 12-20-12 02.00.29 Bumped MPI2_HEADER_VERSION_UNIT. 82 | * Added MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET. 83 | * 04-09-13 02.00.30 Bumped MPI2_HEADER_VERSION_UNIT. 84 | * 04-17-13 02.00.31 Bumped MPI2_HEADER_VERSION_UNIT. 85 | * 08-19-13 02.00.32 Bumped MPI2_HEADER_VERSION_UNIT. 86 | * 12-05-13 02.00.33 Bumped MPI2_HEADER_VERSION_UNIT. 87 | * 01-08-14 02.00.34 Bumped MPI2_HEADER_VERSION_UNIT. 88 | * 06-13-14 02.00.35 Bumped MPI2_HEADER_VERSION_UNIT. 89 | * -------------------------------------------------------------------------- 90 | */ 91 | 92 | #ifndef MPI2_H 93 | #define MPI2_H 94 | 95 | 96 | /***************************************************************************** 97 | * 98 | * MPI Version Definitions 99 | * 100 | *****************************************************************************/ 101 | 102 | #define MPI2_VERSION_MAJOR (0x02) 103 | #define MPI2_VERSION_MINOR (0x00) 104 | #define MPI2_VERSION_MAJOR_MASK (0xFF00) 105 | #define MPI2_VERSION_MAJOR_SHIFT (8) 106 | #define MPI2_VERSION_MINOR_MASK (0x00FF) 107 | #define MPI2_VERSION_MINOR_SHIFT (0) 108 | #define MPI2_VERSION ((MPI2_VERSION_MAJOR << MPI2_VERSION_MAJOR_SHIFT) | \ 109 | MPI2_VERSION_MINOR) 110 | 111 | #define MPI2_VERSION_02_00 (0x0200) 112 | 113 | /* versioning for this MPI header set */ 114 | #define MPI2_HEADER_VERSION_UNIT (0x23) 115 | #define MPI2_HEADER_VERSION_DEV (0x00) 116 | #define MPI2_HEADER_VERSION_UNIT_MASK (0xFF00) 117 | #define MPI2_HEADER_VERSION_UNIT_SHIFT (8) 118 | #define MPI2_HEADER_VERSION_DEV_MASK (0x00FF) 119 | #define MPI2_HEADER_VERSION_DEV_SHIFT (0) 120 | #define MPI2_HEADER_VERSION ((MPI2_HEADER_VERSION_UNIT << 8) | MPI2_HEADER_VERSION_DEV) 121 | 122 | 123 | /***************************************************************************** 124 | * 125 | * IOC State Definitions 126 | * 127 | *****************************************************************************/ 128 | 129 | #define MPI2_IOC_STATE_RESET (0x00000000) 130 | #define MPI2_IOC_STATE_READY (0x10000000) 131 | #define MPI2_IOC_STATE_OPERATIONAL (0x20000000) 132 | #define MPI2_IOC_STATE_FAULT (0x40000000) 133 | 134 | #define MPI2_IOC_STATE_MASK (0xF0000000) 135 | #define MPI2_IOC_STATE_SHIFT (28) 136 | 137 | /* Fault state range for prodcut specific codes */ 138 | #define MPI2_FAULT_PRODUCT_SPECIFIC_MIN (0x0000) 139 | #define MPI2_FAULT_PRODUCT_SPECIFIC_MAX (0xEFFF) 140 | 141 | 142 | /***************************************************************************** 143 | * 144 | * System Interface Register Definitions 145 | * 146 | *****************************************************************************/ 147 | 148 | typedef volatile struct _MPI2_SYSTEM_INTERFACE_REGS 149 | { 150 | U32 Doorbell; /* 0x00 */ 151 | U32 WriteSequence; /* 0x04 */ 152 | U32 HostDiagnostic; /* 0x08 */ 153 | U32 Reserved1; /* 0x0C */ 154 | U32 DiagRWData; /* 0x10 */ 155 | U32 DiagRWAddressLow; /* 0x14 */ 156 | U32 DiagRWAddressHigh; /* 0x18 */ 157 | U32 Reserved2[5]; /* 0x1C */ 158 | U32 HostInterruptStatus; /* 0x30 */ 159 | U32 HostInterruptMask; /* 0x34 */ 160 | U32 DCRData; /* 0x38 */ 161 | U32 DCRAddress; /* 0x3C */ 162 | U32 Reserved3[2]; /* 0x40 */ 163 | U32 ReplyFreeHostIndex; /* 0x48 */ 164 | U32 Reserved4[8]; /* 0x4C */ 165 | U32 ReplyPostHostIndex; /* 0x6C */ 166 | U32 Reserved5; /* 0x70 */ 167 | U32 HCBSize; /* 0x74 */ 168 | U32 HCBAddressLow; /* 0x78 */ 169 | U32 HCBAddressHigh; /* 0x7C */ 170 | U32 Reserved6[16]; /* 0x80 */ 171 | U32 RequestDescriptorPostLow; /* 0xC0 */ 172 | U32 RequestDescriptorPostHigh; /* 0xC4 */ 173 | U32 Reserved7[14]; /* 0xC8 */ 174 | } MPI2_SYSTEM_INTERFACE_REGS, MPI2_POINTER PTR_MPI2_SYSTEM_INTERFACE_REGS, 175 | Mpi2SystemInterfaceRegs_t, MPI2_POINTER pMpi2SystemInterfaceRegs_t; 176 | 177 | /* 178 | * Defines for working with the Doorbell register. 179 | */ 180 | #define MPI2_DOORBELL_OFFSET (0x00000000) 181 | 182 | /* IOC --> System values */ 183 | #define MPI2_DOORBELL_USED (0x08000000) 184 | #define MPI2_DOORBELL_WHO_INIT_MASK (0x07000000) 185 | #define MPI2_DOORBELL_WHO_INIT_SHIFT (24) 186 | #define MPI2_DOORBELL_FAULT_CODE_MASK (0x0000FFFF) 187 | #define MPI2_DOORBELL_DATA_MASK (0x0000FFFF) 188 | 189 | /* System --> IOC values */ 190 | #define MPI2_DOORBELL_FUNCTION_MASK (0xFF000000) 191 | #define MPI2_DOORBELL_FUNCTION_SHIFT (24) 192 | #define MPI2_DOORBELL_ADD_DWORDS_MASK (0x00FF0000) 193 | #define MPI2_DOORBELL_ADD_DWORDS_SHIFT (16) 194 | 195 | 196 | /* 197 | * Defines for the WriteSequence register 198 | */ 199 | #define MPI2_WRITE_SEQUENCE_OFFSET (0x00000004) 200 | #define MPI2_WRSEQ_KEY_VALUE_MASK (0x0000000F) 201 | #define MPI2_WRSEQ_FLUSH_KEY_VALUE (0x0) 202 | #define MPI2_WRSEQ_1ST_KEY_VALUE (0xF) 203 | #define MPI2_WRSEQ_2ND_KEY_VALUE (0x4) 204 | #define MPI2_WRSEQ_3RD_KEY_VALUE (0xB) 205 | #define MPI2_WRSEQ_4TH_KEY_VALUE (0x2) 206 | #define MPI2_WRSEQ_5TH_KEY_VALUE (0x7) 207 | #define MPI2_WRSEQ_6TH_KEY_VALUE (0xD) 208 | 209 | /* 210 | * Defines for the HostDiagnostic register 211 | */ 212 | #define MPI2_HOST_DIAGNOSTIC_OFFSET (0x00000008) 213 | 214 | #define MPI2_DIAG_BOOT_DEVICE_SELECT_MASK (0x00001800) 215 | #define MPI2_DIAG_BOOT_DEVICE_SELECT_DEFAULT (0x00000000) 216 | #define MPI2_DIAG_BOOT_DEVICE_SELECT_HCDW (0x00000800) 217 | 218 | #define MPI2_DIAG_CLEAR_FLASH_BAD_SIG (0x00000400) 219 | #define MPI2_DIAG_FORCE_HCB_ON_RESET (0x00000200) 220 | #define MPI2_DIAG_HCB_MODE (0x00000100) 221 | #define MPI2_DIAG_DIAG_WRITE_ENABLE (0x00000080) 222 | #define MPI2_DIAG_FLASH_BAD_SIG (0x00000040) 223 | #define MPI2_DIAG_RESET_HISTORY (0x00000020) 224 | #define MPI2_DIAG_DIAG_RW_ENABLE (0x00000010) 225 | #define MPI2_DIAG_RESET_ADAPTER (0x00000004) 226 | #define MPI2_DIAG_HOLD_IOC_RESET (0x00000002) 227 | 228 | /* 229 | * Offsets for DiagRWData and address 230 | */ 231 | #define MPI2_DIAG_RW_DATA_OFFSET (0x00000010) 232 | #define MPI2_DIAG_RW_ADDRESS_LOW_OFFSET (0x00000014) 233 | #define MPI2_DIAG_RW_ADDRESS_HIGH_OFFSET (0x00000018) 234 | 235 | /* 236 | * Defines for the HostInterruptStatus register 237 | */ 238 | #define MPI2_HOST_INTERRUPT_STATUS_OFFSET (0x00000030) 239 | #define MPI2_HIS_SYS2IOC_DB_STATUS (0x80000000) 240 | #define MPI2_HIS_IOP_DOORBELL_STATUS MPI2_HIS_SYS2IOC_DB_STATUS 241 | #define MPI2_HIS_RESET_IRQ_STATUS (0x40000000) 242 | #define MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT (0x00000008) 243 | #define MPI2_HIS_IOC2SYS_DB_STATUS (0x00000001) 244 | #define MPI2_HIS_DOORBELL_INTERRUPT MPI2_HIS_IOC2SYS_DB_STATUS 245 | 246 | /* 247 | * Defines for the HostInterruptMask register 248 | */ 249 | #define MPI2_HOST_INTERRUPT_MASK_OFFSET (0x00000034) 250 | #define MPI2_HIM_RESET_IRQ_MASK (0x40000000) 251 | #define MPI2_HIM_REPLY_INT_MASK (0x00000008) 252 | #define MPI2_HIM_RIM MPI2_HIM_REPLY_INT_MASK 253 | #define MPI2_HIM_IOC2SYS_DB_MASK (0x00000001) 254 | #define MPI2_HIM_DIM MPI2_HIM_IOC2SYS_DB_MASK 255 | 256 | /* 257 | * Offsets for DCRData and address 258 | */ 259 | #define MPI2_DCR_DATA_OFFSET (0x00000038) 260 | #define MPI2_DCR_ADDRESS_OFFSET (0x0000003C) 261 | 262 | /* 263 | * Offset for the Reply Free Queue 264 | */ 265 | #define MPI2_REPLY_FREE_HOST_INDEX_OFFSET (0x00000048) 266 | 267 | /* 268 | * Defines for the Reply Descriptor Post Queue 269 | */ 270 | #define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C) 271 | #define MPI2_REPLY_POST_HOST_INDEX_MASK (0x00FFFFFF) 272 | #define MPI2_RPHI_MSIX_INDEX_MASK (0xFF000000) 273 | #define MPI2_RPHI_MSIX_INDEX_SHIFT (24) 274 | #define MPI25_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C) /* MPI v2.5 only */ 275 | 276 | /* 277 | * Defines for the HCBSize and address 278 | */ 279 | #define MPI2_HCB_SIZE_OFFSET (0x00000074) 280 | #define MPI2_HCB_SIZE_SIZE_MASK (0xFFFFF000) 281 | #define MPI2_HCB_SIZE_HCB_ENABLE (0x00000001) 282 | 283 | #define MPI2_HCB_ADDRESS_LOW_OFFSET (0x00000078) 284 | #define MPI2_HCB_ADDRESS_HIGH_OFFSET (0x0000007C) 285 | 286 | /* 287 | * Offsets for the Request Queue 288 | */ 289 | #define MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET (0x000000C0) 290 | #define MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET (0x000000C4) 291 | 292 | 293 | /* Hard Reset delay timings */ 294 | #define MPI2_HARD_RESET_PCIE_FIRST_READ_DELAY_MICRO_SEC (50000) 295 | #define MPI2_HARD_RESET_PCIE_RESET_READ_WINDOW_MICRO_SEC (255000) 296 | #define MPI2_HARD_RESET_PCIE_SECOND_READ_DELAY_MICRO_SEC (256000) 297 | 298 | /***************************************************************************** 299 | * 300 | * Message Descriptors 301 | * 302 | *****************************************************************************/ 303 | 304 | /* Request Descriptors */ 305 | 306 | /* Default Request Descriptor */ 307 | typedef struct _MPI2_DEFAULT_REQUEST_DESCRIPTOR 308 | { 309 | U8 RequestFlags; /* 0x00 */ 310 | U8 MSIxIndex; /* 0x01 */ 311 | U16 SMID; /* 0x02 */ 312 | U16 LMID; /* 0x04 */ 313 | U16 DescriptorTypeDependent; /* 0x06 */ 314 | } MPI2_DEFAULT_REQUEST_DESCRIPTOR, 315 | MPI2_POINTER PTR_MPI2_DEFAULT_REQUEST_DESCRIPTOR, 316 | Mpi2DefaultRequestDescriptor_t, MPI2_POINTER pMpi2DefaultRequestDescriptor_t; 317 | 318 | /* defines for the RequestFlags field */ 319 | #define MPI2_REQ_DESCRIPT_FLAGS_TYPE_MASK (0x0E) 320 | #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO (0x00) 321 | #define MPI2_REQ_DESCRIPT_FLAGS_SCSI_TARGET (0x02) 322 | #define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x06) 323 | #define MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE (0x08) 324 | #define MPI2_REQ_DESCRIPT_FLAGS_RAID_ACCELERATOR (0x0A) 325 | 326 | #define MPI2_REQ_DESCRIPT_FLAGS_IOC_FIFO_MARKER (0x01) 327 | 328 | 329 | /* High Priority Request Descriptor */ 330 | typedef struct _MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR 331 | { 332 | U8 RequestFlags; /* 0x00 */ 333 | U8 MSIxIndex; /* 0x01 */ 334 | U16 SMID; /* 0x02 */ 335 | U16 LMID; /* 0x04 */ 336 | U16 Reserved1; /* 0x06 */ 337 | } MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR, 338 | MPI2_POINTER PTR_MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR, 339 | Mpi2HighPriorityRequestDescriptor_t, 340 | MPI2_POINTER pMpi2HighPriorityRequestDescriptor_t; 341 | 342 | 343 | /* SCSI IO Request Descriptor */ 344 | typedef struct _MPI2_SCSI_IO_REQUEST_DESCRIPTOR 345 | { 346 | U8 RequestFlags; /* 0x00 */ 347 | U8 MSIxIndex; /* 0x01 */ 348 | U16 SMID; /* 0x02 */ 349 | U16 LMID; /* 0x04 */ 350 | U16 DevHandle; /* 0x06 */ 351 | } MPI2_SCSI_IO_REQUEST_DESCRIPTOR, 352 | MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST_DESCRIPTOR, 353 | Mpi2SCSIIORequestDescriptor_t, MPI2_POINTER pMpi2SCSIIORequestDescriptor_t; 354 | 355 | 356 | /* SCSI Target Request Descriptor */ 357 | typedef struct _MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR 358 | { 359 | U8 RequestFlags; /* 0x00 */ 360 | U8 MSIxIndex; /* 0x01 */ 361 | U16 SMID; /* 0x02 */ 362 | U16 LMID; /* 0x04 */ 363 | U16 IoIndex; /* 0x06 */ 364 | } MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR, 365 | MPI2_POINTER PTR_MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR, 366 | Mpi2SCSITargetRequestDescriptor_t, 367 | MPI2_POINTER pMpi2SCSITargetRequestDescriptor_t; 368 | 369 | 370 | /* RAID Accelerator Request Descriptor */ 371 | typedef struct _MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR { 372 | U8 RequestFlags; /* 0x00 */ 373 | U8 MSIxIndex; /* 0x01 */ 374 | U16 SMID; /* 0x02 */ 375 | U16 LMID; /* 0x04 */ 376 | U16 Reserved; /* 0x06 */ 377 | } MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, 378 | MPI2_POINTER PTR_MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR, 379 | Mpi2RAIDAcceleratorRequestDescriptor_t, 380 | MPI2_POINTER pMpi2RAIDAcceleratorRequestDescriptor_t; 381 | 382 | 383 | /* union of Request Descriptors */ 384 | typedef union _MPI2_REQUEST_DESCRIPTOR_UNION 385 | { 386 | MPI2_DEFAULT_REQUEST_DESCRIPTOR Default; 387 | MPI2_HIGH_PRIORITY_REQUEST_DESCRIPTOR HighPriority; 388 | MPI2_SCSI_IO_REQUEST_DESCRIPTOR SCSIIO; 389 | MPI2_SCSI_TARGET_REQUEST_DESCRIPTOR SCSITarget; 390 | MPI2_RAID_ACCEL_REQUEST_DESCRIPTOR RAIDAccelerator; 391 | U64 Words; 392 | } MPI2_REQUEST_DESCRIPTOR_UNION, MPI2_POINTER PTR_MPI2_REQUEST_DESCRIPTOR_UNION, 393 | Mpi2RequestDescriptorUnion_t, MPI2_POINTER pMpi2RequestDescriptorUnion_t; 394 | 395 | 396 | /* Reply Descriptors */ 397 | 398 | /* Default Reply Descriptor */ 399 | typedef struct _MPI2_DEFAULT_REPLY_DESCRIPTOR 400 | { 401 | U8 ReplyFlags; /* 0x00 */ 402 | U8 MSIxIndex; /* 0x01 */ 403 | U16 DescriptorTypeDependent1; /* 0x02 */ 404 | U32 DescriptorTypeDependent2; /* 0x04 */ 405 | } MPI2_DEFAULT_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY_DESCRIPTOR, 406 | Mpi2DefaultReplyDescriptor_t, MPI2_POINTER pMpi2DefaultReplyDescriptor_t; 407 | 408 | /* defines for the ReplyFlags field */ 409 | #define MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK (0x0F) 410 | #define MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS (0x00) 411 | #define MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY (0x01) 412 | #define MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS (0x02) 413 | #define MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER (0x03) 414 | #define MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS (0x05) 415 | #define MPI2_RPY_DESCRIPT_FLAGS_UNUSED (0x0F) 416 | 417 | /* values for marking a reply descriptor as unused */ 418 | #define MPI2_RPY_DESCRIPT_UNUSED_WORD0_MARK (0xFFFFFFFF) 419 | #define MPI2_RPY_DESCRIPT_UNUSED_WORD1_MARK (0xFFFFFFFF) 420 | 421 | /* Address Reply Descriptor */ 422 | typedef struct _MPI2_ADDRESS_REPLY_DESCRIPTOR 423 | { 424 | U8 ReplyFlags; /* 0x00 */ 425 | U8 MSIxIndex; /* 0x01 */ 426 | U16 SMID; /* 0x02 */ 427 | U32 ReplyFrameAddress; /* 0x04 */ 428 | } MPI2_ADDRESS_REPLY_DESCRIPTOR, MPI2_POINTER PTR_MPI2_ADDRESS_REPLY_DESCRIPTOR, 429 | Mpi2AddressReplyDescriptor_t, MPI2_POINTER pMpi2AddressReplyDescriptor_t; 430 | 431 | #define MPI2_ADDRESS_REPLY_SMID_INVALID (0x00) 432 | 433 | 434 | /* SCSI IO Success Reply Descriptor */ 435 | typedef struct _MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR 436 | { 437 | U8 ReplyFlags; /* 0x00 */ 438 | U8 MSIxIndex; /* 0x01 */ 439 | U16 SMID; /* 0x02 */ 440 | U16 TaskTag; /* 0x04 */ 441 | U16 Reserved1; /* 0x06 */ 442 | } MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, 443 | MPI2_POINTER PTR_MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR, 444 | Mpi2SCSIIOSuccessReplyDescriptor_t, 445 | MPI2_POINTER pMpi2SCSIIOSuccessReplyDescriptor_t; 446 | 447 | 448 | /* TargetAssist Success Reply Descriptor */ 449 | typedef struct _MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR 450 | { 451 | U8 ReplyFlags; /* 0x00 */ 452 | U8 MSIxIndex; /* 0x01 */ 453 | U16 SMID; /* 0x02 */ 454 | U8 SequenceNumber; /* 0x04 */ 455 | U8 Reserved1; /* 0x05 */ 456 | U16 IoIndex; /* 0x06 */ 457 | } MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR, 458 | MPI2_POINTER PTR_MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR, 459 | Mpi2TargetAssistSuccessReplyDescriptor_t, 460 | MPI2_POINTER pMpi2TargetAssistSuccessReplyDescriptor_t; 461 | 462 | 463 | /* Target Command Buffer Reply Descriptor */ 464 | typedef struct _MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR 465 | { 466 | U8 ReplyFlags; /* 0x00 */ 467 | U8 MSIxIndex; /* 0x01 */ 468 | U8 VP_ID; /* 0x02 */ 469 | U8 Flags; /* 0x03 */ 470 | U16 InitiatorDevHandle; /* 0x04 */ 471 | U16 IoIndex; /* 0x06 */ 472 | } MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR, 473 | MPI2_POINTER PTR_MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR, 474 | Mpi2TargetCommandBufferReplyDescriptor_t, 475 | MPI2_POINTER pMpi2TargetCommandBufferReplyDescriptor_t; 476 | 477 | /* defines for Flags field */ 478 | #define MPI2_RPY_DESCRIPT_TCB_FLAGS_PHYNUM_MASK (0x3F) 479 | 480 | 481 | /* RAID Accelerator Success Reply Descriptor */ 482 | typedef struct _MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR { 483 | U8 ReplyFlags; /* 0x00 */ 484 | U8 MSIxIndex; /* 0x01 */ 485 | U16 SMID; /* 0x02 */ 486 | U32 Reserved; /* 0x04 */ 487 | } MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, 488 | MPI2_POINTER PTR_MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR, 489 | Mpi2RAIDAcceleratorSuccessReplyDescriptor_t, 490 | MPI2_POINTER pMpi2RAIDAcceleratorSuccessReplyDescriptor_t; 491 | 492 | 493 | /* union of Reply Descriptors */ 494 | typedef union _MPI2_REPLY_DESCRIPTORS_UNION 495 | { 496 | MPI2_DEFAULT_REPLY_DESCRIPTOR Default; 497 | MPI2_ADDRESS_REPLY_DESCRIPTOR AddressReply; 498 | MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR SCSIIOSuccess; 499 | MPI2_TARGETASSIST_SUCCESS_REPLY_DESCRIPTOR TargetAssistSuccess; 500 | MPI2_TARGET_COMMAND_BUFFER_REPLY_DESCRIPTOR TargetCommandBuffer; 501 | MPI2_RAID_ACCELERATOR_SUCCESS_REPLY_DESCRIPTOR RAIDAcceleratorSuccess; 502 | U64 Words; 503 | } MPI2_REPLY_DESCRIPTORS_UNION, MPI2_POINTER PTR_MPI2_REPLY_DESCRIPTORS_UNION, 504 | Mpi2ReplyDescriptorsUnion_t, MPI2_POINTER pMpi2ReplyDescriptorsUnion_t; 505 | 506 | 507 | 508 | /***************************************************************************** 509 | * 510 | * Message Functions 511 | * 512 | *****************************************************************************/ 513 | 514 | #define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO */ 515 | #define MPI2_FUNCTION_SCSI_TASK_MGMT (0x01) /* SCSI Task Management */ 516 | #define MPI2_FUNCTION_IOC_INIT (0x02) /* IOC Init */ 517 | #define MPI2_FUNCTION_IOC_FACTS (0x03) /* IOC Facts */ 518 | #define MPI2_FUNCTION_CONFIG (0x04) /* Configuration */ 519 | #define MPI2_FUNCTION_PORT_FACTS (0x05) /* Port Facts */ 520 | #define MPI2_FUNCTION_PORT_ENABLE (0x06) /* Port Enable */ 521 | #define MPI2_FUNCTION_EVENT_NOTIFICATION (0x07) /* Event Notification */ 522 | #define MPI2_FUNCTION_EVENT_ACK (0x08) /* Event Acknowledge */ 523 | #define MPI2_FUNCTION_FW_DOWNLOAD (0x09) /* FW Download */ 524 | #define MPI2_FUNCTION_TARGET_ASSIST (0x0B) /* Target Assist */ 525 | #define MPI2_FUNCTION_TARGET_STATUS_SEND (0x0C) /* Target Status Send */ 526 | #define MPI2_FUNCTION_TARGET_MODE_ABORT (0x0D) /* Target Mode Abort */ 527 | #define MPI2_FUNCTION_FW_UPLOAD (0x12) /* FW Upload */ 528 | #define MPI2_FUNCTION_RAID_ACTION (0x15) /* RAID Action */ 529 | #define MPI2_FUNCTION_RAID_SCSI_IO_PASSTHROUGH (0x16) /* SCSI IO RAID Passthrough */ 530 | #define MPI2_FUNCTION_TOOLBOX (0x17) /* Toolbox */ 531 | #define MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR (0x18) /* SCSI Enclosure Processor */ 532 | #define MPI2_FUNCTION_SMP_PASSTHROUGH (0x1A) /* SMP Passthrough */ 533 | #define MPI2_FUNCTION_SAS_IO_UNIT_CONTROL (0x1B) /* SAS IO Unit Control */ 534 | #define MPI2_FUNCTION_SATA_PASSTHROUGH (0x1C) /* SATA Passthrough */ 535 | #define MPI2_FUNCTION_DIAG_BUFFER_POST (0x1D) /* Diagnostic Buffer Post */ 536 | #define MPI2_FUNCTION_DIAG_RELEASE (0x1E) /* Diagnostic Release */ 537 | #define MPI2_FUNCTION_TARGET_CMD_BUF_BASE_POST (0x24) /* Target Command Buffer Post Base */ 538 | #define MPI2_FUNCTION_TARGET_CMD_BUF_LIST_POST (0x25) /* Target Command Buffer Post List */ 539 | #define MPI2_FUNCTION_RAID_ACCELERATOR (0x2C) /* RAID Accelerator*/ 540 | /* Host Based Discovery Action */ 541 | #define MPI2_FUNCTION_HOST_BASED_DISCOVERY_ACTION (0x2F) 542 | /* Power Management Control */ 543 | #define MPI2_FUNCTION_PWR_MGMT_CONTROL (0x30) 544 | /* Send Host Message */ 545 | #define MPI2_FUNCTION_SEND_HOST_MESSAGE (0x31) 546 | /* beginning of product-specific range */ 547 | #define MPI2_FUNCTION_MIN_PRODUCT_SPECIFIC (0xF0) 548 | /* end of product-specific range */ 549 | #define MPI2_FUNCTION_MAX_PRODUCT_SPECIFIC (0xFF) 550 | 551 | 552 | 553 | 554 | /* Doorbell functions */ 555 | #define MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET (0x40) 556 | #define MPI2_FUNCTION_HANDSHAKE (0x42) 557 | 558 | 559 | /***************************************************************************** 560 | * 561 | * IOC Status Values 562 | * 563 | *****************************************************************************/ 564 | 565 | /* mask for IOCStatus status value */ 566 | #define MPI2_IOCSTATUS_MASK (0x7FFF) 567 | 568 | /**************************************************************************** 569 | * Common IOCStatus values for all replies 570 | ****************************************************************************/ 571 | 572 | #define MPI2_IOCSTATUS_SUCCESS (0x0000) 573 | #define MPI2_IOCSTATUS_INVALID_FUNCTION (0x0001) 574 | #define MPI2_IOCSTATUS_BUSY (0x0002) 575 | #define MPI2_IOCSTATUS_INVALID_SGL (0x0003) 576 | #define MPI2_IOCSTATUS_INTERNAL_ERROR (0x0004) 577 | #define MPI2_IOCSTATUS_INVALID_VPID (0x0005) 578 | #define MPI2_IOCSTATUS_INSUFFICIENT_RESOURCES (0x0006) 579 | #define MPI2_IOCSTATUS_INVALID_FIELD (0x0007) 580 | #define MPI2_IOCSTATUS_INVALID_STATE (0x0008) 581 | #define MPI2_IOCSTATUS_OP_STATE_NOT_SUPPORTED (0x0009) 582 | 583 | /**************************************************************************** 584 | * Config IOCStatus values 585 | ****************************************************************************/ 586 | 587 | #define MPI2_IOCSTATUS_CONFIG_INVALID_ACTION (0x0020) 588 | #define MPI2_IOCSTATUS_CONFIG_INVALID_TYPE (0x0021) 589 | #define MPI2_IOCSTATUS_CONFIG_INVALID_PAGE (0x0022) 590 | #define MPI2_IOCSTATUS_CONFIG_INVALID_DATA (0x0023) 591 | #define MPI2_IOCSTATUS_CONFIG_NO_DEFAULTS (0x0024) 592 | #define MPI2_IOCSTATUS_CONFIG_CANT_COMMIT (0x0025) 593 | 594 | /**************************************************************************** 595 | * SCSI IO Reply 596 | ****************************************************************************/ 597 | 598 | #define MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR (0x0040) 599 | #define MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE (0x0042) 600 | #define MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE (0x0043) 601 | #define MPI2_IOCSTATUS_SCSI_DATA_OVERRUN (0x0044) 602 | #define MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN (0x0045) 603 | #define MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR (0x0046) 604 | #define MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR (0x0047) 605 | #define MPI2_IOCSTATUS_SCSI_TASK_TERMINATED (0x0048) 606 | #define MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH (0x0049) 607 | #define MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED (0x004A) 608 | #define MPI2_IOCSTATUS_SCSI_IOC_TERMINATED (0x004B) 609 | #define MPI2_IOCSTATUS_SCSI_EXT_TERMINATED (0x004C) 610 | 611 | /**************************************************************************** 612 | * For use by SCSI Initiator and SCSI Target end-to-end data protection 613 | ****************************************************************************/ 614 | 615 | #define MPI2_IOCSTATUS_EEDP_GUARD_ERROR (0x004D) 616 | #define MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR (0x004E) 617 | #define MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR (0x004F) 618 | 619 | /**************************************************************************** 620 | * SCSI Target values 621 | ****************************************************************************/ 622 | 623 | #define MPI2_IOCSTATUS_TARGET_INVALID_IO_INDEX (0x0062) 624 | #define MPI2_IOCSTATUS_TARGET_ABORTED (0x0063) 625 | #define MPI2_IOCSTATUS_TARGET_NO_CONN_RETRYABLE (0x0064) 626 | #define MPI2_IOCSTATUS_TARGET_NO_CONNECTION (0x0065) 627 | #define MPI2_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH (0x006A) 628 | #define MPI2_IOCSTATUS_TARGET_DATA_OFFSET_ERROR (0x006D) 629 | #define MPI2_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA (0x006E) 630 | #define MPI2_IOCSTATUS_TARGET_IU_TOO_SHORT (0x006F) 631 | #define MPI2_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT (0x0070) 632 | #define MPI2_IOCSTATUS_TARGET_NAK_RECEIVED (0x0071) 633 | 634 | /**************************************************************************** 635 | * Serial Attached SCSI values 636 | ****************************************************************************/ 637 | 638 | #define MPI2_IOCSTATUS_SAS_SMP_REQUEST_FAILED (0x0090) 639 | #define MPI2_IOCSTATUS_SAS_SMP_DATA_OVERRUN (0x0091) 640 | 641 | /**************************************************************************** 642 | * Diagnostic Buffer Post / Diagnostic Release values 643 | ****************************************************************************/ 644 | 645 | #define MPI2_IOCSTATUS_DIAGNOSTIC_RELEASED (0x00A0) 646 | 647 | /**************************************************************************** 648 | * RAID Accelerator values 649 | ****************************************************************************/ 650 | 651 | #define MPI2_IOCSTATUS_RAID_ACCEL_ERROR (0x00B0) 652 | 653 | /**************************************************************************** 654 | * IOCStatus flag to indicate that log info is available 655 | ****************************************************************************/ 656 | 657 | #define MPI2_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE (0x8000) 658 | 659 | /**************************************************************************** 660 | * IOCLogInfo Types 661 | ****************************************************************************/ 662 | 663 | #define MPI2_IOCLOGINFO_TYPE_MASK (0xF0000000) 664 | #define MPI2_IOCLOGINFO_TYPE_SHIFT (28) 665 | #define MPI2_IOCLOGINFO_TYPE_NONE (0x0) 666 | #define MPI2_IOCLOGINFO_TYPE_SCSI (0x1) 667 | #define MPI2_IOCLOGINFO_TYPE_FC (0x2) 668 | #define MPI2_IOCLOGINFO_TYPE_SAS (0x3) 669 | #define MPI2_IOCLOGINFO_TYPE_ISCSI (0x4) 670 | #define MPI2_IOCLOGINFO_LOG_DATA_MASK (0x0FFFFFFF) 671 | 672 | 673 | /***************************************************************************** 674 | * 675 | * Standard Message Structures 676 | * 677 | *****************************************************************************/ 678 | 679 | /**************************************************************************** 680 | * Request Message Header for all request messages 681 | ****************************************************************************/ 682 | 683 | typedef struct _MPI2_REQUEST_HEADER 684 | { 685 | U16 FunctionDependent1; /* 0x00 */ 686 | U8 ChainOffset; /* 0x02 */ 687 | U8 Function; /* 0x03 */ 688 | U16 FunctionDependent2; /* 0x04 */ 689 | U8 FunctionDependent3; /* 0x06 */ 690 | U8 MsgFlags; /* 0x07 */ 691 | U8 VP_ID; /* 0x08 */ 692 | U8 VF_ID; /* 0x09 */ 693 | U16 Reserved1; /* 0x0A */ 694 | } MPI2_REQUEST_HEADER, MPI2_POINTER PTR_MPI2_REQUEST_HEADER, 695 | MPI2RequestHeader_t, MPI2_POINTER pMPI2RequestHeader_t; 696 | 697 | 698 | /**************************************************************************** 699 | * Default Reply 700 | ****************************************************************************/ 701 | 702 | typedef struct _MPI2_DEFAULT_REPLY 703 | { 704 | U16 FunctionDependent1; /* 0x00 */ 705 | U8 MsgLength; /* 0x02 */ 706 | U8 Function; /* 0x03 */ 707 | U16 FunctionDependent2; /* 0x04 */ 708 | U8 FunctionDependent3; /* 0x06 */ 709 | U8 MsgFlags; /* 0x07 */ 710 | U8 VP_ID; /* 0x08 */ 711 | U8 VF_ID; /* 0x09 */ 712 | U16 Reserved1; /* 0x0A */ 713 | U16 FunctionDependent5; /* 0x0C */ 714 | U16 IOCStatus; /* 0x0E */ 715 | U32 IOCLogInfo; /* 0x10 */ 716 | } MPI2_DEFAULT_REPLY, MPI2_POINTER PTR_MPI2_DEFAULT_REPLY, 717 | MPI2DefaultReply_t, MPI2_POINTER pMPI2DefaultReply_t; 718 | 719 | 720 | /* common version structure/union used in messages and configuration pages */ 721 | 722 | typedef struct _MPI2_VERSION_STRUCT 723 | { 724 | U8 Dev; /* 0x00 */ 725 | U8 Unit; /* 0x01 */ 726 | U8 Minor; /* 0x02 */ 727 | U8 Major; /* 0x03 */ 728 | } MPI2_VERSION_STRUCT; 729 | 730 | typedef union _MPI2_VERSION_UNION 731 | { 732 | MPI2_VERSION_STRUCT Struct; 733 | U32 Word; 734 | } MPI2_VERSION_UNION; 735 | 736 | 737 | /* LUN field defines, common to many structures */ 738 | #define MPI2_LUN_FIRST_LEVEL_ADDRESSING (0x0000FFFF) 739 | #define MPI2_LUN_SECOND_LEVEL_ADDRESSING (0xFFFF0000) 740 | #define MPI2_LUN_THIRD_LEVEL_ADDRESSING (0x0000FFFF) 741 | #define MPI2_LUN_FOURTH_LEVEL_ADDRESSING (0xFFFF0000) 742 | #define MPI2_LUN_LEVEL_1_WORD (0xFF00) 743 | #define MPI2_LUN_LEVEL_1_DWORD (0x0000FF00) 744 | 745 | 746 | /***************************************************************************** 747 | * 748 | * Fusion-MPT MPI Scatter Gather Elements 749 | * 750 | *****************************************************************************/ 751 | 752 | /**************************************************************************** 753 | * MPI Simple Element structures 754 | ****************************************************************************/ 755 | 756 | typedef struct _MPI2_SGE_SIMPLE32 757 | { 758 | U32 FlagsLength; 759 | U32 Address; 760 | } MPI2_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_SGE_SIMPLE32, 761 | Mpi2SGESimple32_t, MPI2_POINTER pMpi2SGESimple32_t; 762 | 763 | typedef struct _MPI2_SGE_SIMPLE64 764 | { 765 | U32 FlagsLength; 766 | U64 Address; 767 | } MPI2_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_SGE_SIMPLE64, 768 | Mpi2SGESimple64_t, MPI2_POINTER pMpi2SGESimple64_t; 769 | 770 | typedef struct _MPI2_SGE_SIMPLE_UNION 771 | { 772 | U32 FlagsLength; 773 | union 774 | { 775 | U32 Address32; 776 | U64 Address64; 777 | } u; 778 | } MPI2_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_SIMPLE_UNION, 779 | Mpi2SGESimpleUnion_t, MPI2_POINTER pMpi2SGESimpleUnion_t; 780 | 781 | 782 | /**************************************************************************** 783 | * MPI Chain Element structures 784 | ****************************************************************************/ 785 | 786 | typedef struct _MPI2_SGE_CHAIN32 787 | { 788 | U16 Length; 789 | U8 NextChainOffset; 790 | U8 Flags; 791 | U32 Address; 792 | } MPI2_SGE_CHAIN32, MPI2_POINTER PTR_MPI2_SGE_CHAIN32, 793 | Mpi2SGEChain32_t, MPI2_POINTER pMpi2SGEChain32_t; 794 | 795 | typedef struct _MPI2_SGE_CHAIN64 796 | { 797 | U16 Length; 798 | U8 NextChainOffset; 799 | U8 Flags; 800 | U64 Address; 801 | } MPI2_SGE_CHAIN64, MPI2_POINTER PTR_MPI2_SGE_CHAIN64, 802 | Mpi2SGEChain64_t, MPI2_POINTER pMpi2SGEChain64_t; 803 | 804 | typedef struct _MPI2_SGE_CHAIN_UNION 805 | { 806 | U16 Length; 807 | U8 NextChainOffset; 808 | U8 Flags; 809 | union 810 | { 811 | U32 Address32; 812 | U64 Address64; 813 | } u; 814 | } MPI2_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_SGE_CHAIN_UNION, 815 | Mpi2SGEChainUnion_t, MPI2_POINTER pMpi2SGEChainUnion_t; 816 | 817 | 818 | /**************************************************************************** 819 | * MPI Transaction Context Element structures 820 | ****************************************************************************/ 821 | 822 | typedef struct _MPI2_SGE_TRANSACTION32 823 | { 824 | U8 Reserved; 825 | U8 ContextSize; 826 | U8 DetailsLength; 827 | U8 Flags; 828 | U32 TransactionContext[1]; 829 | U32 TransactionDetails[1]; 830 | } MPI2_SGE_TRANSACTION32, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION32, 831 | Mpi2SGETransaction32_t, MPI2_POINTER pMpi2SGETransaction32_t; 832 | 833 | typedef struct _MPI2_SGE_TRANSACTION64 834 | { 835 | U8 Reserved; 836 | U8 ContextSize; 837 | U8 DetailsLength; 838 | U8 Flags; 839 | U32 TransactionContext[2]; 840 | U32 TransactionDetails[1]; 841 | } MPI2_SGE_TRANSACTION64, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION64, 842 | Mpi2SGETransaction64_t, MPI2_POINTER pMpi2SGETransaction64_t; 843 | 844 | typedef struct _MPI2_SGE_TRANSACTION96 845 | { 846 | U8 Reserved; 847 | U8 ContextSize; 848 | U8 DetailsLength; 849 | U8 Flags; 850 | U32 TransactionContext[3]; 851 | U32 TransactionDetails[1]; 852 | } MPI2_SGE_TRANSACTION96, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION96, 853 | Mpi2SGETransaction96_t, MPI2_POINTER pMpi2SGETransaction96_t; 854 | 855 | typedef struct _MPI2_SGE_TRANSACTION128 856 | { 857 | U8 Reserved; 858 | U8 ContextSize; 859 | U8 DetailsLength; 860 | U8 Flags; 861 | U32 TransactionContext[4]; 862 | U32 TransactionDetails[1]; 863 | } MPI2_SGE_TRANSACTION128, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION128, 864 | Mpi2SGETransaction_t128, MPI2_POINTER pMpi2SGETransaction_t128; 865 | 866 | typedef struct _MPI2_SGE_TRANSACTION_UNION 867 | { 868 | U8 Reserved; 869 | U8 ContextSize; 870 | U8 DetailsLength; 871 | U8 Flags; 872 | union 873 | { 874 | U32 TransactionContext32[1]; 875 | U32 TransactionContext64[2]; 876 | U32 TransactionContext96[3]; 877 | U32 TransactionContext128[4]; 878 | } u; 879 | U32 TransactionDetails[1]; 880 | } MPI2_SGE_TRANSACTION_UNION, MPI2_POINTER PTR_MPI2_SGE_TRANSACTION_UNION, 881 | Mpi2SGETransactionUnion_t, MPI2_POINTER pMpi2SGETransactionUnion_t; 882 | 883 | 884 | /**************************************************************************** 885 | * MPI SGE union for IO SGL's 886 | ****************************************************************************/ 887 | 888 | typedef struct _MPI2_MPI_SGE_IO_UNION 889 | { 890 | union 891 | { 892 | MPI2_SGE_SIMPLE_UNION Simple; 893 | MPI2_SGE_CHAIN_UNION Chain; 894 | } u; 895 | } MPI2_MPI_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_MPI_SGE_IO_UNION, 896 | Mpi2MpiSGEIOUnion_t, MPI2_POINTER pMpi2MpiSGEIOUnion_t; 897 | 898 | 899 | /**************************************************************************** 900 | * MPI SGE union for SGL's with Simple and Transaction elements 901 | ****************************************************************************/ 902 | 903 | typedef struct _MPI2_SGE_TRANS_SIMPLE_UNION 904 | { 905 | union 906 | { 907 | MPI2_SGE_SIMPLE_UNION Simple; 908 | MPI2_SGE_TRANSACTION_UNION Transaction; 909 | } u; 910 | } MPI2_SGE_TRANS_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_SGE_TRANS_SIMPLE_UNION, 911 | Mpi2SGETransSimpleUnion_t, MPI2_POINTER pMpi2SGETransSimpleUnion_t; 912 | 913 | 914 | /**************************************************************************** 915 | * All MPI SGE types union 916 | ****************************************************************************/ 917 | 918 | typedef struct _MPI2_MPI_SGE_UNION 919 | { 920 | union 921 | { 922 | MPI2_SGE_SIMPLE_UNION Simple; 923 | MPI2_SGE_CHAIN_UNION Chain; 924 | MPI2_SGE_TRANSACTION_UNION Transaction; 925 | } u; 926 | } MPI2_MPI_SGE_UNION, MPI2_POINTER PTR_MPI2_MPI_SGE_UNION, 927 | Mpi2MpiSgeUnion_t, MPI2_POINTER pMpi2MpiSgeUnion_t; 928 | 929 | 930 | /**************************************************************************** 931 | * MPI SGE field definition and masks 932 | ****************************************************************************/ 933 | 934 | /* Flags field bit definitions */ 935 | 936 | #define MPI2_SGE_FLAGS_LAST_ELEMENT (0x80) 937 | #define MPI2_SGE_FLAGS_END_OF_BUFFER (0x40) 938 | #define MPI2_SGE_FLAGS_ELEMENT_TYPE_MASK (0x30) 939 | #define MPI2_SGE_FLAGS_LOCAL_ADDRESS (0x08) 940 | #define MPI2_SGE_FLAGS_DIRECTION (0x04) 941 | #define MPI2_SGE_FLAGS_ADDRESS_SIZE (0x02) 942 | #define MPI2_SGE_FLAGS_END_OF_LIST (0x01) 943 | 944 | #define MPI2_SGE_FLAGS_SHIFT (24) 945 | 946 | #define MPI2_SGE_LENGTH_MASK (0x00FFFFFF) 947 | #define MPI2_SGE_CHAIN_LENGTH_MASK (0x0000FFFF) 948 | 949 | /* Element Type */ 950 | 951 | #define MPI2_SGE_FLAGS_TRANSACTION_ELEMENT (0x00) 952 | #define MPI2_SGE_FLAGS_SIMPLE_ELEMENT (0x10) 953 | #define MPI2_SGE_FLAGS_CHAIN_ELEMENT (0x30) 954 | #define MPI2_SGE_FLAGS_ELEMENT_MASK (0x30) 955 | 956 | /* Address location */ 957 | 958 | #define MPI2_SGE_FLAGS_SYSTEM_ADDRESS (0x00) 959 | 960 | /* Direction */ 961 | 962 | #define MPI2_SGE_FLAGS_IOC_TO_HOST (0x00) 963 | #define MPI2_SGE_FLAGS_HOST_TO_IOC (0x04) 964 | 965 | #define MPI2_SGE_FLAGS_DEST (MPI2_SGE_FLAGS_IOC_TO_HOST) 966 | #define MPI2_SGE_FLAGS_SOURCE (MPI2_SGE_FLAGS_HOST_TO_IOC) 967 | 968 | /* Address Size */ 969 | 970 | #define MPI2_SGE_FLAGS_32_BIT_ADDRESSING (0x00) 971 | #define MPI2_SGE_FLAGS_64_BIT_ADDRESSING (0x02) 972 | 973 | /* Context Size */ 974 | 975 | #define MPI2_SGE_FLAGS_32_BIT_CONTEXT (0x00) 976 | #define MPI2_SGE_FLAGS_64_BIT_CONTEXT (0x02) 977 | #define MPI2_SGE_FLAGS_96_BIT_CONTEXT (0x04) 978 | #define MPI2_SGE_FLAGS_128_BIT_CONTEXT (0x06) 979 | 980 | #define MPI2_SGE_CHAIN_OFFSET_MASK (0x00FF0000) 981 | #define MPI2_SGE_CHAIN_OFFSET_SHIFT (16) 982 | 983 | /**************************************************************************** 984 | * MPI SGE operation Macros 985 | ****************************************************************************/ 986 | 987 | /* SIMPLE FlagsLength manipulations... */ 988 | #define MPI2_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_SGE_FLAGS_SHIFT) 989 | #define MPI2_SGE_GET_FLAGS(f) (((f) & ~MPI2_SGE_LENGTH_MASK) >> MPI2_SGE_FLAGS_SHIFT) 990 | #define MPI2_SGE_LENGTH(f) ((f) & MPI2_SGE_LENGTH_MASK) 991 | #define MPI2_SGE_CHAIN_LENGTH(f) ((f) & MPI2_SGE_CHAIN_LENGTH_MASK) 992 | 993 | #define MPI2_SGE_SET_FLAGS_LENGTH(f,l) (MPI2_SGE_SET_FLAGS(f) | MPI2_SGE_LENGTH(l)) 994 | 995 | #define MPI2_pSGE_GET_FLAGS(psg) MPI2_SGE_GET_FLAGS((psg)->FlagsLength) 996 | #define MPI2_pSGE_GET_LENGTH(psg) MPI2_SGE_LENGTH((psg)->FlagsLength) 997 | #define MPI2_pSGE_SET_FLAGS_LENGTH(psg,f,l) (psg)->FlagsLength = MPI2_SGE_SET_FLAGS_LENGTH(f,l) 998 | 999 | /* CAUTION - The following are READ-MODIFY-WRITE! */ 1000 | #define MPI2_pSGE_SET_FLAGS(psg,f) (psg)->FlagsLength |= MPI2_SGE_SET_FLAGS(f) 1001 | #define MPI2_pSGE_SET_LENGTH(psg,l) (psg)->FlagsLength |= MPI2_SGE_LENGTH(l) 1002 | 1003 | #define MPI2_GET_CHAIN_OFFSET(x) ((x & MPI2_SGE_CHAIN_OFFSET_MASK) >> MPI2_SGE_CHAIN_OFFSET_SHIFT) 1004 | 1005 | 1006 | /***************************************************************************** 1007 | * 1008 | * Fusion-MPT IEEE Scatter Gather Elements 1009 | * 1010 | *****************************************************************************/ 1011 | 1012 | /**************************************************************************** 1013 | * IEEE Simple Element structures 1014 | ****************************************************************************/ 1015 | 1016 | typedef struct _MPI2_IEEE_SGE_SIMPLE32 1017 | { 1018 | U32 Address; 1019 | U32 FlagsLength; 1020 | } MPI2_IEEE_SGE_SIMPLE32, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE32, 1021 | Mpi2IeeeSgeSimple32_t, MPI2_POINTER pMpi2IeeeSgeSimple32_t; 1022 | 1023 | typedef struct _MPI2_IEEE_SGE_SIMPLE64 1024 | { 1025 | U64 Address; 1026 | U32 Length; 1027 | U16 Reserved1; 1028 | U8 Reserved2; 1029 | U8 Flags; 1030 | } MPI2_IEEE_SGE_SIMPLE64, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE64, 1031 | Mpi2IeeeSgeSimple64_t, MPI2_POINTER pMpi2IeeeSgeSimple64_t; 1032 | 1033 | typedef union _MPI2_IEEE_SGE_SIMPLE_UNION 1034 | { 1035 | MPI2_IEEE_SGE_SIMPLE32 Simple32; 1036 | MPI2_IEEE_SGE_SIMPLE64 Simple64; 1037 | } MPI2_IEEE_SGE_SIMPLE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_SIMPLE_UNION, 1038 | Mpi2IeeeSgeSimpleUnion_t, MPI2_POINTER pMpi2IeeeSgeSimpleUnion_t; 1039 | 1040 | 1041 | /**************************************************************************** 1042 | * IEEE Chain Element structures 1043 | ****************************************************************************/ 1044 | 1045 | typedef MPI2_IEEE_SGE_SIMPLE32 MPI2_IEEE_SGE_CHAIN32; 1046 | 1047 | typedef MPI2_IEEE_SGE_SIMPLE64 MPI2_IEEE_SGE_CHAIN64; 1048 | 1049 | typedef union _MPI2_IEEE_SGE_CHAIN_UNION 1050 | { 1051 | MPI2_IEEE_SGE_CHAIN32 Chain32; 1052 | MPI2_IEEE_SGE_CHAIN64 Chain64; 1053 | } MPI2_IEEE_SGE_CHAIN_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_CHAIN_UNION, 1054 | Mpi2IeeeSgeChainUnion_t, MPI2_POINTER pMpi2IeeeSgeChainUnion_t; 1055 | 1056 | 1057 | /**************************************************************************** 1058 | * All IEEE SGE types union 1059 | ****************************************************************************/ 1060 | 1061 | typedef struct _MPI2_IEEE_SGE_UNION 1062 | { 1063 | union 1064 | { 1065 | MPI2_IEEE_SGE_SIMPLE_UNION Simple; 1066 | MPI2_IEEE_SGE_CHAIN_UNION Chain; 1067 | } u; 1068 | } MPI2_IEEE_SGE_UNION, MPI2_POINTER PTR_MPI2_IEEE_SGE_UNION, 1069 | Mpi2IeeeSgeUnion_t, MPI2_POINTER pMpi2IeeeSgeUnion_t; 1070 | 1071 | 1072 | /**************************************************************************** 1073 | * IEEE SGE field definitions and masks 1074 | ****************************************************************************/ 1075 | 1076 | /* Flags field bit definitions */ 1077 | 1078 | #define MPI2_IEEE_SGE_FLAGS_ELEMENT_TYPE_MASK (0x80) 1079 | 1080 | #define MPI2_IEEE32_SGE_FLAGS_SHIFT (24) 1081 | 1082 | #define MPI2_IEEE32_SGE_LENGTH_MASK (0x00FFFFFF) 1083 | 1084 | /* Element Type */ 1085 | 1086 | #define MPI2_IEEE_SGE_FLAGS_SIMPLE_ELEMENT (0x00) 1087 | #define MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT (0x80) 1088 | 1089 | /* Data Location Address Space */ 1090 | 1091 | #define MPI2_IEEE_SGE_FLAGS_ADDR_MASK (0x03) 1092 | #define MPI2_IEEE_SGE_FLAGS_SYSTEM_ADDR (0x00) 1093 | /* IEEE Simple Element only */ 1094 | #define MPI2_IEEE_SGE_FLAGS_IOCDDR_ADDR (0x01) 1095 | /* IEEE Simple Element only */ 1096 | #define MPI2_IEEE_SGE_FLAGS_IOCPLB_ADDR (0x02) 1097 | #define MPI2_IEEE_SGE_FLAGS_IOCPLBNTA_ADDR (0x03) 1098 | /* IEEE Simple Element only */ 1099 | #define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR (0x03) 1100 | /* IEEE Chain Element only */ 1101 | #define MPI2_IEEE_SGE_FLAGS_SYSTEMPLBCPI_ADDR \ 1102 | (MPI2_IEEE_SGE_FLAGS_SYSTEMPLBPCI_ADDR) /* typo in name */ 1103 | 1104 | /**************************************************************************** 1105 | * IEEE SGE operation Macros 1106 | ****************************************************************************/ 1107 | 1108 | /* SIMPLE FlagsLength manipulations... */ 1109 | #define MPI2_IEEE32_SGE_SET_FLAGS(f) ((U32)(f) << MPI2_IEEE32_SGE_FLAGS_SHIFT) 1110 | #define MPI2_IEEE32_SGE_GET_FLAGS(f) (((f) & ~MPI2_IEEE32_SGE_LENGTH_MASK) >> MPI2_IEEE32_SGE_FLAGS_SHIFT) 1111 | #define MPI2_IEEE32_SGE_LENGTH(f) ((f) & MPI2_IEEE32_SGE_LENGTH_MASK) 1112 | 1113 | #define MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f, l) (MPI2_IEEE32_SGE_SET_FLAGS(f) | MPI2_IEEE32_SGE_LENGTH(l)) 1114 | 1115 | #define MPI2_IEEE32_pSGE_GET_FLAGS(psg) MPI2_IEEE32_SGE_GET_FLAGS((psg)->FlagsLength) 1116 | #define MPI2_IEEE32_pSGE_GET_LENGTH(psg) MPI2_IEEE32_SGE_LENGTH((psg)->FlagsLength) 1117 | #define MPI2_IEEE32_pSGE_SET_FLAGS_LENGTH(psg,f,l) (psg)->FlagsLength = MPI2_IEEE32_SGE_SET_FLAGS_LENGTH(f,l) 1118 | 1119 | /* CAUTION - The following are READ-MODIFY-WRITE! */ 1120 | #define MPI2_IEEE32_pSGE_SET_FLAGS(psg,f) (psg)->FlagsLength |= MPI2_IEEE32_SGE_SET_FLAGS(f) 1121 | #define MPI2_IEEE32_pSGE_SET_LENGTH(psg,l) (psg)->FlagsLength |= MPI2_IEEE32_SGE_LENGTH(l) 1122 | 1123 | 1124 | 1125 | 1126 | /***************************************************************************** 1127 | * 1128 | * Fusion-MPT MPI/IEEE Scatter Gather Unions 1129 | * 1130 | *****************************************************************************/ 1131 | 1132 | typedef union _MPI2_SIMPLE_SGE_UNION 1133 | { 1134 | MPI2_SGE_SIMPLE_UNION MpiSimple; 1135 | MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; 1136 | } MPI2_SIMPLE_SGE_UNION, MPI2_POINTER PTR_MPI2_SIMPLE_SGE_UNION, 1137 | Mpi2SimpleSgeUntion_t, MPI2_POINTER pMpi2SimpleSgeUntion_t; 1138 | 1139 | 1140 | typedef union _MPI2_SGE_IO_UNION 1141 | { 1142 | MPI2_SGE_SIMPLE_UNION MpiSimple; 1143 | MPI2_SGE_CHAIN_UNION MpiChain; 1144 | MPI2_IEEE_SGE_SIMPLE_UNION IeeeSimple; 1145 | MPI2_IEEE_SGE_CHAIN_UNION IeeeChain; 1146 | } MPI2_SGE_IO_UNION, MPI2_POINTER PTR_MPI2_SGE_IO_UNION, 1147 | Mpi2SGEIOUnion_t, MPI2_POINTER pMpi2SGEIOUnion_t; 1148 | 1149 | 1150 | /**************************************************************************** 1151 | * 1152 | * Values for SGLFlags field, used in many request messages with an SGL 1153 | * 1154 | ****************************************************************************/ 1155 | 1156 | /* values for MPI SGL Data Location Address Space subfield */ 1157 | #define MPI2_SGLFLAGS_ADDRESS_SPACE_MASK (0x0C) 1158 | #define MPI2_SGLFLAGS_SYSTEM_ADDRESS_SPACE (0x00) 1159 | #define MPI2_SGLFLAGS_IOCDDR_ADDRESS_SPACE (0x04) 1160 | #define MPI2_SGLFLAGS_IOCPLB_ADDRESS_SPACE (0x08) 1161 | #define MPI2_SGLFLAGS_IOCPLBNTA_ADDRESS_SPACE (0x0C) 1162 | /* values for SGL Type subfield */ 1163 | #define MPI2_SGLFLAGS_SGL_TYPE_MASK (0x03) 1164 | #define MPI2_SGLFLAGS_SGL_TYPE_MPI (0x00) 1165 | #define MPI2_SGLFLAGS_SGL_TYPE_IEEE32 (0x01) 1166 | #define MPI2_SGLFLAGS_SGL_TYPE_IEEE64 (0x02) 1167 | 1168 | 1169 | #endif 1170 | 1171 | -------------------------------------------------------------------------------- /mpt/mpi/mpi2_init.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2014 LSI Corporation. 3 | * 4 | * 5 | * Name: mpi2_init.h 6 | * Title: MPI SCSI initiator mode messages and structures 7 | * Creation Date: June 23, 2006 8 | * 9 | * mpi2_init.h Version: 02.00.15 10 | * 11 | * Version History 12 | * --------------- 13 | * 14 | * Date Version Description 15 | * -------- -------- ------------------------------------------------------ 16 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. 17 | * 10-31-07 02.00.01 Fixed name for pMpi2SCSITaskManagementRequest_t. 18 | * 12-18-07 02.00.02 Modified Task Management Target Reset Method defines. 19 | * 02-29-08 02.00.03 Added Query Task Set and Query Unit Attention. 20 | * 03-03-08 02.00.04 Fixed name of struct _MPI2_SCSI_TASK_MANAGE_REPLY. 21 | * 05-21-08 02.00.05 Fixed typo in name of Mpi2SepRequest_t. 22 | * 10-02-08 02.00.06 Removed Untagged and No Disconnect values from SCSI IO 23 | * Control field Task Attribute flags. 24 | * Moved LUN field defines to mpi2.h because they are 25 | * common to many structures. 26 | * 05-06-09 02.00.07 Changed task management type of Query Unit Attention to 27 | * Query Asynchronous Event. 28 | * Defined two new bits in the SlotStatus field of the SCSI 29 | * Enclosure Processor Request and Reply. 30 | * 10-28-09 02.00.08 Added defines for decoding the ResponseInfo bytes for 31 | * both SCSI IO Error Reply and SCSI Task Management Reply. 32 | * Added ResponseInfo field to MPI2_SCSI_TASK_MANAGE_REPLY. 33 | * Added MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG define. 34 | * 02-10-10 02.00.09 Removed unused structure that had "#if 0" around it. 35 | * 05-12-10 02.00.10 Added optional vendor-unique region to SCSI IO Request. 36 | * 11-10-10 02.00.11 Added MPI2_SCSIIO_NUM_SGLOFFSETS define. 37 | * 02-06-12 02.00.13 Added alternate defines for Task Priority / Command 38 | * Priority to match SAM-4. 39 | * 07-10-12 02.00.14 Added MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION. 40 | * 04-09-13 02.00.15 Added SCSIStatusQualifier field to MPI2_SCSI_IO_REPLY, 41 | * replacing the Reserved4 field. 42 | * -------------------------------------------------------------------------- 43 | */ 44 | 45 | #ifndef MPI2_INIT_H 46 | #define MPI2_INIT_H 47 | 48 | /***************************************************************************** 49 | * 50 | * SCSI Initiator Messages 51 | * 52 | *****************************************************************************/ 53 | 54 | /**************************************************************************** 55 | * SCSI IO messages and associated structures 56 | ****************************************************************************/ 57 | 58 | typedef struct 59 | { 60 | U8 CDB[20]; /* 0x00 */ 61 | U32 PrimaryReferenceTag; /* 0x14 */ 62 | U16 PrimaryApplicationTag; /* 0x18 */ 63 | U16 PrimaryApplicationTagMask; /* 0x1A */ 64 | U32 TransferLength; /* 0x1C */ 65 | } MPI2_SCSI_IO_CDB_EEDP32, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_EEDP32, 66 | Mpi2ScsiIoCdbEedp32_t, MPI2_POINTER pMpi2ScsiIoCdbEedp32_t; 67 | 68 | typedef union 69 | { 70 | U8 CDB32[32]; 71 | MPI2_SCSI_IO_CDB_EEDP32 EEDP32; 72 | MPI2_SGE_SIMPLE_UNION SGE; 73 | } MPI2_SCSI_IO_CDB_UNION, MPI2_POINTER PTR_MPI2_SCSI_IO_CDB_UNION, 74 | Mpi2ScsiIoCdb_t, MPI2_POINTER pMpi2ScsiIoCdb_t; 75 | 76 | /* SCSI IO Request Message */ 77 | typedef struct _MPI2_SCSI_IO_REQUEST 78 | { 79 | U16 DevHandle; /* 0x00 */ 80 | U8 ChainOffset; /* 0x02 */ 81 | U8 Function; /* 0x03 */ 82 | U16 Reserved1; /* 0x04 */ 83 | U8 Reserved2; /* 0x06 */ 84 | U8 MsgFlags; /* 0x07 */ 85 | U8 VP_ID; /* 0x08 */ 86 | U8 VF_ID; /* 0x09 */ 87 | U16 Reserved3; /* 0x0A */ 88 | U32 SenseBufferLowAddress; /* 0x0C */ 89 | U16 SGLFlags; /* 0x10 */ 90 | U8 SenseBufferLength; /* 0x12 */ 91 | U8 Reserved4; /* 0x13 */ 92 | U8 SGLOffset0; /* 0x14 */ 93 | U8 SGLOffset1; /* 0x15 */ 94 | U8 SGLOffset2; /* 0x16 */ 95 | U8 SGLOffset3; /* 0x17 */ 96 | U32 SkipCount; /* 0x18 */ 97 | U32 DataLength; /* 0x1C */ 98 | U32 BidirectionalDataLength; /* 0x20 */ 99 | U16 IoFlags; /* 0x24 */ 100 | U16 EEDPFlags; /* 0x26 */ 101 | U32 EEDPBlockSize; /* 0x28 */ 102 | U32 SecondaryReferenceTag; /* 0x2C */ 103 | U16 SecondaryApplicationTag; /* 0x30 */ 104 | U16 ApplicationTagTranslationMask; /* 0x32 */ 105 | U8 LUN[8]; /* 0x34 */ 106 | U32 Control; /* 0x3C */ 107 | MPI2_SCSI_IO_CDB_UNION CDB; /* 0x40 */ 108 | 109 | #ifdef MPI2_SCSI_IO_VENDOR_UNIQUE_REGION /* typically this is left undefined */ 110 | MPI2_SCSI_IO_VENDOR_UNIQUE VendorRegion; 111 | #endif 112 | 113 | MPI2_SGE_IO_UNION SGL; /* 0x60 */ 114 | 115 | } MPI2_SCSI_IO_REQUEST, MPI2_POINTER PTR_MPI2_SCSI_IO_REQUEST, 116 | Mpi2SCSIIORequest_t, MPI2_POINTER pMpi2SCSIIORequest_t; 117 | 118 | /* SCSI IO MsgFlags bits */ 119 | 120 | /* MsgFlags for SenseBufferAddressSpace */ 121 | #define MPI2_SCSIIO_MSGFLAGS_MASK_SENSE_ADDR (0x0C) 122 | #define MPI2_SCSIIO_MSGFLAGS_SYSTEM_SENSE_ADDR (0x00) 123 | #define MPI2_SCSIIO_MSGFLAGS_IOCDDR_SENSE_ADDR (0x04) 124 | #define MPI2_SCSIIO_MSGFLAGS_IOCPLB_SENSE_ADDR (0x08) 125 | #define MPI2_SCSIIO_MSGFLAGS_IOCPLBNTA_SENSE_ADDR (0x0C) 126 | 127 | /* SCSI IO SGLFlags bits */ 128 | 129 | /* base values for Data Location Address Space */ 130 | #define MPI2_SCSIIO_SGLFLAGS_ADDR_MASK (0x0C) 131 | #define MPI2_SCSIIO_SGLFLAGS_SYSTEM_ADDR (0x00) 132 | #define MPI2_SCSIIO_SGLFLAGS_IOCDDR_ADDR (0x04) 133 | #define MPI2_SCSIIO_SGLFLAGS_IOCPLB_ADDR (0x08) 134 | #define MPI2_SCSIIO_SGLFLAGS_IOCPLBNTA_ADDR (0x0C) 135 | 136 | /* base values for Type */ 137 | #define MPI2_SCSIIO_SGLFLAGS_TYPE_MASK (0x03) 138 | #define MPI2_SCSIIO_SGLFLAGS_TYPE_MPI (0x00) 139 | #define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE32 (0x01) 140 | #define MPI2_SCSIIO_SGLFLAGS_TYPE_IEEE64 (0x02) 141 | 142 | /* shift values for each sub-field */ 143 | #define MPI2_SCSIIO_SGLFLAGS_SGL3_SHIFT (12) 144 | #define MPI2_SCSIIO_SGLFLAGS_SGL2_SHIFT (8) 145 | #define MPI2_SCSIIO_SGLFLAGS_SGL1_SHIFT (4) 146 | #define MPI2_SCSIIO_SGLFLAGS_SGL0_SHIFT (0) 147 | 148 | /* number of SGLOffset fields */ 149 | #define MPI2_SCSIIO_NUM_SGLOFFSETS (4) 150 | 151 | /* SCSI IO IoFlags bits */ 152 | 153 | /* Large CDB Address Space */ 154 | #define MPI2_SCSIIO_CDB_ADDR_MASK (0x6000) 155 | #define MPI2_SCSIIO_CDB_ADDR_SYSTEM (0x0000) 156 | #define MPI2_SCSIIO_CDB_ADDR_IOCDDR (0x2000) 157 | #define MPI2_SCSIIO_CDB_ADDR_IOCPLB (0x4000) 158 | #define MPI2_SCSIIO_CDB_ADDR_IOCPLBNTA (0x6000) 159 | 160 | #define MPI2_SCSIIO_IOFLAGS_LARGE_CDB (0x1000) 161 | #define MPI2_SCSIIO_IOFLAGS_BIDIRECTIONAL (0x0800) 162 | #define MPI2_SCSIIO_IOFLAGS_MULTICAST (0x0400) 163 | #define MPI2_SCSIIO_IOFLAGS_CMD_DETERMINES_DATA_DIR (0x0200) 164 | #define MPI2_SCSIIO_IOFLAGS_CDBLENGTH_MASK (0x01FF) 165 | 166 | /* SCSI IO EEDPFlags bits */ 167 | 168 | #define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG (0x8000) 169 | #define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_REFTAG (0x4000) 170 | #define MPI2_SCSIIO_EEDPFLAGS_INC_PRI_APPTAG (0x2000) 171 | #define MPI2_SCSIIO_EEDPFLAGS_INC_SEC_APPTAG (0x1000) 172 | 173 | #define MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG (0x0400) 174 | #define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200) 175 | #define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100) 176 | 177 | #define MPI2_SCSIIO_EEDPFLAGS_PASSTHRU_REFTAG (0x0008) 178 | 179 | #define MPI2_SCSIIO_EEDPFLAGS_MASK_OP (0x0007) 180 | #define MPI2_SCSIIO_EEDPFLAGS_NOOP_OP (0x0000) 181 | #define MPI2_SCSIIO_EEDPFLAGS_CHECK_OP (0x0001) 182 | #define MPI2_SCSIIO_EEDPFLAGS_STRIP_OP (0x0002) 183 | #define MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP (0x0003) 184 | #define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004) 185 | #define MPI2_SCSIIO_EEDPFLAGS_REPLACE_OP (0x0006) 186 | #define MPI2_SCSIIO_EEDPFLAGS_CHECK_REGEN_OP (0x0007) 187 | 188 | /* SCSI IO LUN fields: use MPI2_LUN_ from mpi2.h */ 189 | 190 | /* SCSI IO Control bits */ 191 | #define MPI2_SCSIIO_CONTROL_ADDCDBLEN_MASK (0xFC000000) 192 | #define MPI2_SCSIIO_CONTROL_ADDCDBLEN_SHIFT (26) 193 | 194 | #define MPI2_SCSIIO_CONTROL_DATADIRECTION_MASK (0x03000000) 195 | #define MPI2_SCSIIO_CONTROL_SHIFT_DATADIRECTION (24) 196 | #define MPI2_SCSIIO_CONTROL_NODATATRANSFER (0x00000000) 197 | #define MPI2_SCSIIO_CONTROL_WRITE (0x01000000) 198 | #define MPI2_SCSIIO_CONTROL_READ (0x02000000) 199 | #define MPI2_SCSIIO_CONTROL_BIDIRECTIONAL (0x03000000) 200 | 201 | #define MPI2_SCSIIO_CONTROL_TASKPRI_MASK (0x00007800) 202 | #define MPI2_SCSIIO_CONTROL_TASKPRI_SHIFT (11) 203 | /* alternate name for the previous field; called Command Priority in SAM-4 */ 204 | #define MPI2_SCSIIO_CONTROL_CMDPRI_MASK (0x00007800) 205 | #define MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT (11) 206 | 207 | #define MPI2_SCSIIO_CONTROL_TASKATTRIBUTE_MASK (0x00000700) 208 | #define MPI2_SCSIIO_CONTROL_SIMPLEQ (0x00000000) 209 | #define MPI2_SCSIIO_CONTROL_HEADOFQ (0x00000100) 210 | #define MPI2_SCSIIO_CONTROL_ORDEREDQ (0x00000200) 211 | #define MPI2_SCSIIO_CONTROL_ACAQ (0x00000400) 212 | 213 | #define MPI2_SCSIIO_CONTROL_TLR_MASK (0x000000C0) 214 | #define MPI2_SCSIIO_CONTROL_NO_TLR (0x00000000) 215 | #define MPI2_SCSIIO_CONTROL_TLR_ON (0x00000040) 216 | #define MPI2_SCSIIO_CONTROL_TLR_OFF (0x00000080) 217 | 218 | 219 | /* SCSI IO Error Reply Message */ 220 | typedef struct _MPI2_SCSI_IO_REPLY 221 | { 222 | U16 DevHandle; /* 0x00 */ 223 | U8 MsgLength; /* 0x02 */ 224 | U8 Function; /* 0x03 */ 225 | U16 Reserved1; /* 0x04 */ 226 | U8 Reserved2; /* 0x06 */ 227 | U8 MsgFlags; /* 0x07 */ 228 | U8 VP_ID; /* 0x08 */ 229 | U8 VF_ID; /* 0x09 */ 230 | U16 Reserved3; /* 0x0A */ 231 | U8 SCSIStatus; /* 0x0C */ 232 | U8 SCSIState; /* 0x0D */ 233 | U16 IOCStatus; /* 0x0E */ 234 | U32 IOCLogInfo; /* 0x10 */ 235 | U32 TransferCount; /* 0x14 */ 236 | U32 SenseCount; /* 0x18 */ 237 | U32 ResponseInfo; /* 0x1C */ 238 | U16 TaskTag; /* 0x20 */ 239 | U16 SCSIStatusQualifier; /* 0x22 */ 240 | U32 BidirectionalTransferCount; /* 0x24 */ 241 | U32 Reserved5; /* 0x28 */ 242 | U32 Reserved6; /* 0x2C */ 243 | } MPI2_SCSI_IO_REPLY, MPI2_POINTER PTR_MPI2_SCSI_IO_REPLY, 244 | Mpi2SCSIIOReply_t, MPI2_POINTER pMpi2SCSIIOReply_t; 245 | 246 | /* SCSI IO Reply SCSIStatus values (SAM-4 status codes) */ 247 | 248 | #define MPI2_SCSI_STATUS_GOOD (0x00) 249 | #define MPI2_SCSI_STATUS_CHECK_CONDITION (0x02) 250 | #define MPI2_SCSI_STATUS_CONDITION_MET (0x04) 251 | #define MPI2_SCSI_STATUS_BUSY (0x08) 252 | #define MPI2_SCSI_STATUS_INTERMEDIATE (0x10) 253 | #define MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET (0x14) 254 | #define MPI2_SCSI_STATUS_RESERVATION_CONFLICT (0x18) 255 | #define MPI2_SCSI_STATUS_COMMAND_TERMINATED (0x22) /* obsolete */ 256 | #define MPI2_SCSI_STATUS_TASK_SET_FULL (0x28) 257 | #define MPI2_SCSI_STATUS_ACA_ACTIVE (0x30) 258 | #define MPI2_SCSI_STATUS_TASK_ABORTED (0x40) 259 | 260 | /* SCSI IO Reply SCSIState flags */ 261 | 262 | #define MPI2_SCSI_STATE_RESPONSE_INFO_VALID (0x10) 263 | #define MPI2_SCSI_STATE_TERMINATED (0x08) 264 | #define MPI2_SCSI_STATE_NO_SCSI_STATUS (0x04) 265 | #define MPI2_SCSI_STATE_AUTOSENSE_FAILED (0x02) 266 | #define MPI2_SCSI_STATE_AUTOSENSE_VALID (0x01) 267 | 268 | /* masks and shifts for the ResponseInfo field */ 269 | 270 | #define MPI2_SCSI_RI_MASK_REASONCODE (0x000000FF) 271 | #define MPI2_SCSI_RI_SHIFT_REASONCODE (0) 272 | 273 | #define MPI2_SCSI_TASKTAG_UNKNOWN (0xFFFF) 274 | 275 | 276 | /**************************************************************************** 277 | * SCSI Task Management messages 278 | ****************************************************************************/ 279 | 280 | /* SCSI Task Management Request Message */ 281 | typedef struct _MPI2_SCSI_TASK_MANAGE_REQUEST 282 | { 283 | U16 DevHandle; /* 0x00 */ 284 | U8 ChainOffset; /* 0x02 */ 285 | U8 Function; /* 0x03 */ 286 | U8 Reserved1; /* 0x04 */ 287 | U8 TaskType; /* 0x05 */ 288 | U8 Reserved2; /* 0x06 */ 289 | U8 MsgFlags; /* 0x07 */ 290 | U8 VP_ID; /* 0x08 */ 291 | U8 VF_ID; /* 0x09 */ 292 | U16 Reserved3; /* 0x0A */ 293 | U8 LUN[8]; /* 0x0C */ 294 | U32 Reserved4[7]; /* 0x14 */ 295 | U16 TaskMID; /* 0x30 */ 296 | U16 Reserved5; /* 0x32 */ 297 | } MPI2_SCSI_TASK_MANAGE_REQUEST, 298 | MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REQUEST, 299 | Mpi2SCSITaskManagementRequest_t, 300 | MPI2_POINTER pMpi2SCSITaskManagementRequest_t; 301 | 302 | /* TaskType values */ 303 | 304 | #define MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK (0x01) 305 | #define MPI2_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET (0x02) 306 | #define MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET (0x03) 307 | #define MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET (0x05) 308 | #define MPI2_SCSITASKMGMT_TASKTYPE_CLEAR_TASK_SET (0x06) 309 | #define MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK (0x07) 310 | #define MPI2_SCSITASKMGMT_TASKTYPE_CLR_ACA (0x08) 311 | #define MPI2_SCSITASKMGMT_TASKTYPE_QRY_TASK_SET (0x09) 312 | #define MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT (0x0A) 313 | 314 | /* obsolete TaskType name */ 315 | #define MPI2_SCSITASKMGMT_TASKTYPE_QRY_UNIT_ATTENTION \ 316 | (MPI2_SCSITASKMGMT_TASKTYPE_QRY_ASYNC_EVENT) 317 | 318 | /* MsgFlags bits */ 319 | 320 | #define MPI2_SCSITASKMGMT_MSGFLAGS_MASK_TARGET_RESET (0x18) 321 | #define MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET (0x00) 322 | #define MPI2_SCSITASKMGMT_MSGFLAGS_NEXUS_RESET_SRST (0x08) 323 | #define MPI2_SCSITASKMGMT_MSGFLAGS_SAS_HARD_LINK_RESET (0x10) 324 | 325 | #define MPI2_SCSITASKMGMT_MSGFLAGS_DO_NOT_SEND_TASK_IU (0x01) 326 | 327 | 328 | 329 | /* SCSI Task Management Reply Message */ 330 | typedef struct _MPI2_SCSI_TASK_MANAGE_REPLY 331 | { 332 | U16 DevHandle; /* 0x00 */ 333 | U8 MsgLength; /* 0x02 */ 334 | U8 Function; /* 0x03 */ 335 | U8 ResponseCode; /* 0x04 */ 336 | U8 TaskType; /* 0x05 */ 337 | U8 Reserved1; /* 0x06 */ 338 | U8 MsgFlags; /* 0x07 */ 339 | U8 VP_ID; /* 0x08 */ 340 | U8 VF_ID; /* 0x09 */ 341 | U16 Reserved2; /* 0x0A */ 342 | U16 Reserved3; /* 0x0C */ 343 | U16 IOCStatus; /* 0x0E */ 344 | U32 IOCLogInfo; /* 0x10 */ 345 | U32 TerminationCount; /* 0x14 */ 346 | U32 ResponseInfo; /* 0x18 */ 347 | } MPI2_SCSI_TASK_MANAGE_REPLY, 348 | MPI2_POINTER PTR_MPI2_SCSI_TASK_MANAGE_REPLY, 349 | Mpi2SCSITaskManagementReply_t, MPI2_POINTER pMpi2SCSIManagementReply_t; 350 | 351 | /* ResponseCode values */ 352 | 353 | #define MPI2_SCSITASKMGMT_RSP_TM_COMPLETE (0x00) 354 | #define MPI2_SCSITASKMGMT_RSP_INVALID_FRAME (0x02) 355 | #define MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED (0x04) 356 | #define MPI2_SCSITASKMGMT_RSP_TM_FAILED (0x05) 357 | #define MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED (0x08) 358 | #define MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN (0x09) 359 | #define MPI2_SCSITASKMGMT_RSP_TM_OVERLAPPED_TAG (0x0A) 360 | #define MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC (0x80) 361 | 362 | /* masks and shifts for the ResponseInfo field */ 363 | 364 | #define MPI2_SCSITASKMGMT_RI_MASK_REASONCODE (0x000000FF) 365 | #define MPI2_SCSITASKMGMT_RI_SHIFT_REASONCODE (0) 366 | #define MPI2_SCSITASKMGMT_RI_MASK_ARI2 (0x0000FF00) 367 | #define MPI2_SCSITASKMGMT_RI_SHIFT_ARI2 (8) 368 | #define MPI2_SCSITASKMGMT_RI_MASK_ARI1 (0x00FF0000) 369 | #define MPI2_SCSITASKMGMT_RI_SHIFT_ARI1 (16) 370 | #define MPI2_SCSITASKMGMT_RI_MASK_ARI0 (0xFF000000) 371 | #define MPI2_SCSITASKMGMT_RI_SHIFT_ARI0 (24) 372 | 373 | 374 | /**************************************************************************** 375 | * SCSI Enclosure Processor messages 376 | ****************************************************************************/ 377 | 378 | /* SCSI Enclosure Processor Request Message */ 379 | typedef struct _MPI2_SEP_REQUEST 380 | { 381 | U16 DevHandle; /* 0x00 */ 382 | U8 ChainOffset; /* 0x02 */ 383 | U8 Function; /* 0x03 */ 384 | U8 Action; /* 0x04 */ 385 | U8 Flags; /* 0x05 */ 386 | U8 Reserved1; /* 0x06 */ 387 | U8 MsgFlags; /* 0x07 */ 388 | U8 VP_ID; /* 0x08 */ 389 | U8 VF_ID; /* 0x09 */ 390 | U16 Reserved2; /* 0x0A */ 391 | U32 SlotStatus; /* 0x0C */ 392 | U32 Reserved3; /* 0x10 */ 393 | U32 Reserved4; /* 0x14 */ 394 | U32 Reserved5; /* 0x18 */ 395 | U16 Slot; /* 0x1C */ 396 | U16 EnclosureHandle; /* 0x1E */ 397 | } MPI2_SEP_REQUEST, MPI2_POINTER PTR_MPI2_SEP_REQUEST, 398 | Mpi2SepRequest_t, MPI2_POINTER pMpi2SepRequest_t; 399 | 400 | /* Action defines */ 401 | #define MPI2_SEP_REQ_ACTION_WRITE_STATUS (0x00) 402 | #define MPI2_SEP_REQ_ACTION_READ_STATUS (0x01) 403 | 404 | /* Flags defines */ 405 | #define MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS (0x00) 406 | #define MPI2_SEP_REQ_FLAGS_ENCLOSURE_SLOT_ADDRESS (0x01) 407 | 408 | /* SlotStatus defines */ 409 | #define MPI2_SEP_REQ_SLOTSTATUS_REQUEST_REMOVE (0x00040000) 410 | #define MPI2_SEP_REQ_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) 411 | #define MPI2_SEP_REQ_SLOTSTATUS_REBUILD_STOPPED (0x00000200) 412 | #define MPI2_SEP_REQ_SLOTSTATUS_HOT_SPARE (0x00000100) 413 | #define MPI2_SEP_REQ_SLOTSTATUS_UNCONFIGURED (0x00000080) 414 | #define MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT (0x00000040) 415 | #define MPI2_SEP_REQ_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) 416 | #define MPI2_SEP_REQ_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) 417 | #define MPI2_SEP_REQ_SLOTSTATUS_DEV_REBUILDING (0x00000004) 418 | #define MPI2_SEP_REQ_SLOTSTATUS_DEV_FAULTY (0x00000002) 419 | #define MPI2_SEP_REQ_SLOTSTATUS_NO_ERROR (0x00000001) 420 | 421 | 422 | /* SCSI Enclosure Processor Reply Message */ 423 | typedef struct _MPI2_SEP_REPLY 424 | { 425 | U16 DevHandle; /* 0x00 */ 426 | U8 MsgLength; /* 0x02 */ 427 | U8 Function; /* 0x03 */ 428 | U8 Action; /* 0x04 */ 429 | U8 Flags; /* 0x05 */ 430 | U8 Reserved1; /* 0x06 */ 431 | U8 MsgFlags; /* 0x07 */ 432 | U8 VP_ID; /* 0x08 */ 433 | U8 VF_ID; /* 0x09 */ 434 | U16 Reserved2; /* 0x0A */ 435 | U16 Reserved3; /* 0x0C */ 436 | U16 IOCStatus; /* 0x0E */ 437 | U32 IOCLogInfo; /* 0x10 */ 438 | U32 SlotStatus; /* 0x14 */ 439 | U32 Reserved4; /* 0x18 */ 440 | U16 Slot; /* 0x1C */ 441 | U16 EnclosureHandle; /* 0x1E */ 442 | } MPI2_SEP_REPLY, MPI2_POINTER PTR_MPI2_SEP_REPLY, 443 | Mpi2SepReply_t, MPI2_POINTER pMpi2SepReply_t; 444 | 445 | /* SlotStatus defines */ 446 | #define MPI2_SEP_REPLY_SLOTSTATUS_REMOVE_READY (0x00040000) 447 | #define MPI2_SEP_REPLY_SLOTSTATUS_IDENTIFY_REQUEST (0x00020000) 448 | #define MPI2_SEP_REPLY_SLOTSTATUS_REBUILD_STOPPED (0x00000200) 449 | #define MPI2_SEP_REPLY_SLOTSTATUS_HOT_SPARE (0x00000100) 450 | #define MPI2_SEP_REPLY_SLOTSTATUS_UNCONFIGURED (0x00000080) 451 | #define MPI2_SEP_REPLY_SLOTSTATUS_PREDICTED_FAULT (0x00000040) 452 | #define MPI2_SEP_REPLY_SLOTSTATUS_IN_CRITICAL_ARRAY (0x00000010) 453 | #define MPI2_SEP_REPLY_SLOTSTATUS_IN_FAILED_ARRAY (0x00000008) 454 | #define MPI2_SEP_REPLY_SLOTSTATUS_DEV_REBUILDING (0x00000004) 455 | #define MPI2_SEP_REPLY_SLOTSTATUS_DEV_FAULTY (0x00000002) 456 | #define MPI2_SEP_REPLY_SLOTSTATUS_NO_ERROR (0x00000001) 457 | 458 | 459 | #endif 460 | 461 | 462 | -------------------------------------------------------------------------------- /mpt/mpi/mpi2_raid.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2014 LSI Corporation. 3 | * 4 | * 5 | * Name: mpi2_raid.h 6 | * Title: MPI Integrated RAID messages and structures 7 | * Creation Date: April 26, 2007 8 | * 9 | * mpi2_raid.h Version: 02.00.10 10 | * 11 | * Version History 12 | * --------------- 13 | * 14 | * Date Version Description 15 | * -------- -------- ------------------------------------------------------ 16 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. 17 | * 08-31-07 02.00.01 Modifications to RAID Action request and reply, 18 | * including the Actions and ActionData. 19 | * 02-29-08 02.00.02 Added MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD. 20 | * 05-21-08 02.00.03 Added MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS so that 21 | * the PhysDisk array in MPI2_RAID_VOLUME_CREATION_STRUCT 22 | * can be sized by the build environment. 23 | * 07-30-09 02.00.04 Added proper define for the Use Default Settings bit of 24 | * VolumeCreationFlags and marked the old one as obsolete. 25 | * 05-12-10 02.00.05 Added MPI2_RAID_VOL_FLAGS_OP_MDC define. 26 | * 08-24-10 02.00.06 Added MPI2_RAID_ACTION_COMPATIBILITY_CHECK along with 27 | * related structures and defines. 28 | * Added product-specific range to RAID Action values. 29 | * 02-06-12 02.00.08 Added MPI2_RAID_ACTION_PHYSDISK_HIDDEN. 30 | * 07-26-12 02.00.09 Added ElapsedSeconds field to MPI2_RAID_VOL_INDICATOR. 31 | * Added MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID define. 32 | * 04-17-13 02.00.10 Added MPI25_RAID_ACTION_ADATA_ALLOW_PI. 33 | * -------------------------------------------------------------------------- 34 | */ 35 | 36 | #ifndef MPI2_RAID_H 37 | #define MPI2_RAID_H 38 | 39 | /***************************************************************************** 40 | * 41 | * Integrated RAID Messages 42 | * 43 | *****************************************************************************/ 44 | 45 | /**************************************************************************** 46 | * RAID Action messages 47 | ****************************************************************************/ 48 | 49 | /* ActionDataWord defines for use with MPI2_RAID_ACTION_CREATE_VOLUME action */ 50 | #define MPI25_RAID_ACTION_ADATA_ALLOW_PI (0x80000000) 51 | 52 | /* ActionDataWord defines for use with MPI2_RAID_ACTION_DELETE_VOLUME action */ 53 | #define MPI2_RAID_ACTION_ADATA_KEEP_LBA0 (0x00000000) 54 | #define MPI2_RAID_ACTION_ADATA_ZERO_LBA0 (0x00000001) 55 | 56 | /* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ 57 | 58 | /* ActionDataWord defines for use with MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES action */ 59 | #define MPI2_RAID_ACTION_ADATA_DISABL_FULL_REBUILD (0x00000001) 60 | 61 | /* ActionDataWord for MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE Action */ 62 | typedef struct _MPI2_RAID_ACTION_RATE_DATA 63 | { 64 | U8 RateToChange; /* 0x00 */ 65 | U8 RateOrMode; /* 0x01 */ 66 | U16 DataScrubDuration; /* 0x02 */ 67 | } MPI2_RAID_ACTION_RATE_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_RATE_DATA, 68 | Mpi2RaidActionRateData_t, MPI2_POINTER pMpi2RaidActionRateData_t; 69 | 70 | #define MPI2_RAID_ACTION_SET_RATE_RESYNC (0x00) 71 | #define MPI2_RAID_ACTION_SET_RATE_DATA_SCRUB (0x01) 72 | #define MPI2_RAID_ACTION_SET_RATE_POWERSAVE_MODE (0x02) 73 | 74 | /* ActionDataWord for MPI2_RAID_ACTION_START_RAID_FUNCTION Action */ 75 | typedef struct _MPI2_RAID_ACTION_START_RAID_FUNCTION 76 | { 77 | U8 RAIDFunction; /* 0x00 */ 78 | U8 Flags; /* 0x01 */ 79 | U16 Reserved1; /* 0x02 */ 80 | } MPI2_RAID_ACTION_START_RAID_FUNCTION, 81 | MPI2_POINTER PTR_MPI2_RAID_ACTION_START_RAID_FUNCTION, 82 | Mpi2RaidActionStartRaidFunction_t, 83 | MPI2_POINTER pMpi2RaidActionStartRaidFunction_t; 84 | 85 | /* defines for the RAIDFunction field */ 86 | #define MPI2_RAID_ACTION_START_BACKGROUND_INIT (0x00) 87 | #define MPI2_RAID_ACTION_START_ONLINE_CAP_EXPANSION (0x01) 88 | #define MPI2_RAID_ACTION_START_CONSISTENCY_CHECK (0x02) 89 | 90 | /* defines for the Flags field */ 91 | #define MPI2_RAID_ACTION_START_NEW (0x00) 92 | #define MPI2_RAID_ACTION_START_RESUME (0x01) 93 | 94 | /* ActionDataWord for MPI2_RAID_ACTION_STOP_RAID_FUNCTION Action */ 95 | typedef struct _MPI2_RAID_ACTION_STOP_RAID_FUNCTION 96 | { 97 | U8 RAIDFunction; /* 0x00 */ 98 | U8 Flags; /* 0x01 */ 99 | U16 Reserved1; /* 0x02 */ 100 | } MPI2_RAID_ACTION_STOP_RAID_FUNCTION, 101 | MPI2_POINTER PTR_MPI2_RAID_ACTION_STOP_RAID_FUNCTION, 102 | Mpi2RaidActionStopRaidFunction_t, 103 | MPI2_POINTER pMpi2RaidActionStopRaidFunction_t; 104 | 105 | /* defines for the RAIDFunction field */ 106 | #define MPI2_RAID_ACTION_STOP_BACKGROUND_INIT (0x00) 107 | #define MPI2_RAID_ACTION_STOP_ONLINE_CAP_EXPANSION (0x01) 108 | #define MPI2_RAID_ACTION_STOP_CONSISTENCY_CHECK (0x02) 109 | 110 | /* defines for the Flags field */ 111 | #define MPI2_RAID_ACTION_STOP_ABORT (0x00) 112 | #define MPI2_RAID_ACTION_STOP_PAUSE (0x01) 113 | 114 | /* ActionDataWord for MPI2_RAID_ACTION_CREATE_HOT_SPARE Action */ 115 | typedef struct _MPI2_RAID_ACTION_HOT_SPARE 116 | { 117 | U8 HotSparePool; /* 0x00 */ 118 | U8 Reserved1; /* 0x01 */ 119 | U16 DevHandle; /* 0x02 */ 120 | } MPI2_RAID_ACTION_HOT_SPARE, MPI2_POINTER PTR_MPI2_RAID_ACTION_HOT_SPARE, 121 | Mpi2RaidActionHotSpare_t, MPI2_POINTER pMpi2RaidActionHotSpare_t; 122 | 123 | /* ActionDataWord for MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE Action */ 124 | typedef struct _MPI2_RAID_ACTION_FW_UPDATE_MODE 125 | { 126 | U8 Flags; /* 0x00 */ 127 | U8 DeviceFirmwareUpdateModeTimeout; /* 0x01 */ 128 | U16 Reserved1; /* 0x02 */ 129 | } MPI2_RAID_ACTION_FW_UPDATE_MODE, 130 | MPI2_POINTER PTR_MPI2_RAID_ACTION_FW_UPDATE_MODE, 131 | Mpi2RaidActionFwUpdateMode_t, MPI2_POINTER pMpi2RaidActionFwUpdateMode_t; 132 | 133 | /* ActionDataWord defines for use with MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE action */ 134 | #define MPI2_RAID_ACTION_ADATA_DISABLE_FW_UPDATE (0x00) 135 | #define MPI2_RAID_ACTION_ADATA_ENABLE_FW_UPDATE (0x01) 136 | 137 | typedef union _MPI2_RAID_ACTION_DATA 138 | { 139 | U32 Word; 140 | MPI2_RAID_ACTION_RATE_DATA Rates; 141 | MPI2_RAID_ACTION_START_RAID_FUNCTION StartRaidFunction; 142 | MPI2_RAID_ACTION_STOP_RAID_FUNCTION StopRaidFunction; 143 | MPI2_RAID_ACTION_HOT_SPARE HotSpare; 144 | MPI2_RAID_ACTION_FW_UPDATE_MODE FwUpdateMode; 145 | } MPI2_RAID_ACTION_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_DATA, 146 | Mpi2RaidActionData_t, MPI2_POINTER pMpi2RaidActionData_t; 147 | 148 | 149 | /* RAID Action Request Message */ 150 | typedef struct _MPI2_RAID_ACTION_REQUEST 151 | { 152 | U8 Action; /* 0x00 */ 153 | U8 Reserved1; /* 0x01 */ 154 | U8 ChainOffset; /* 0x02 */ 155 | U8 Function; /* 0x03 */ 156 | U16 VolDevHandle; /* 0x04 */ 157 | U8 PhysDiskNum; /* 0x06 */ 158 | U8 MsgFlags; /* 0x07 */ 159 | U8 VP_ID; /* 0x08 */ 160 | U8 VF_ID; /* 0x09 */ 161 | U16 Reserved2; /* 0x0A */ 162 | U32 Reserved3; /* 0x0C */ 163 | MPI2_RAID_ACTION_DATA ActionDataWord; /* 0x10 */ 164 | MPI2_SGE_SIMPLE_UNION ActionDataSGE; /* 0x14 */ 165 | } MPI2_RAID_ACTION_REQUEST, MPI2_POINTER PTR_MPI2_RAID_ACTION_REQUEST, 166 | Mpi2RaidActionRequest_t, MPI2_POINTER pMpi2RaidActionRequest_t; 167 | 168 | /* RAID Action request Action values */ 169 | 170 | #define MPI2_RAID_ACTION_INDICATOR_STRUCT (0x01) 171 | #define MPI2_RAID_ACTION_CREATE_VOLUME (0x02) 172 | #define MPI2_RAID_ACTION_DELETE_VOLUME (0x03) 173 | #define MPI2_RAID_ACTION_DISABLE_ALL_VOLUMES (0x04) 174 | #define MPI2_RAID_ACTION_ENABLE_ALL_VOLUMES (0x05) 175 | #define MPI2_RAID_ACTION_PHYSDISK_OFFLINE (0x0A) 176 | #define MPI2_RAID_ACTION_PHYSDISK_ONLINE (0x0B) 177 | #define MPI2_RAID_ACTION_FAIL_PHYSDISK (0x0F) 178 | #define MPI2_RAID_ACTION_ACTIVATE_VOLUME (0x11) 179 | #define MPI2_RAID_ACTION_DEVICE_FW_UPDATE_MODE (0x15) 180 | #define MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE (0x17) 181 | #define MPI2_RAID_ACTION_SET_VOLUME_NAME (0x18) 182 | #define MPI2_RAID_ACTION_SET_RAID_FUNCTION_RATE (0x19) 183 | #define MPI2_RAID_ACTION_ENABLE_FAILED_VOLUME (0x1C) 184 | #define MPI2_RAID_ACTION_CREATE_HOT_SPARE (0x1D) 185 | #define MPI2_RAID_ACTION_DELETE_HOT_SPARE (0x1E) 186 | #define MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED (0x20) 187 | #define MPI2_RAID_ACTION_START_RAID_FUNCTION (0x21) 188 | #define MPI2_RAID_ACTION_STOP_RAID_FUNCTION (0x22) 189 | #define MPI2_RAID_ACTION_COMPATIBILITY_CHECK (0x23) 190 | #define MPI2_RAID_ACTION_PHYSDISK_HIDDEN (0x24) 191 | #define MPI2_RAID_ACTION_MIN_PRODUCT_SPECIFIC (0x80) 192 | #define MPI2_RAID_ACTION_MAX_PRODUCT_SPECIFIC (0xFF) 193 | 194 | /* RAID Volume Creation Structure */ 195 | 196 | /* 197 | * The following define can be customized for the targeted product. 198 | */ 199 | #ifndef MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS 200 | #define MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS (1) 201 | #endif 202 | 203 | typedef struct _MPI2_RAID_VOLUME_PHYSDISK 204 | { 205 | U8 RAIDSetNum; /* 0x00 */ 206 | U8 PhysDiskMap; /* 0x01 */ 207 | U16 PhysDiskDevHandle; /* 0x02 */ 208 | } MPI2_RAID_VOLUME_PHYSDISK, MPI2_POINTER PTR_MPI2_RAID_VOLUME_PHYSDISK, 209 | Mpi2RaidVolumePhysDisk_t, MPI2_POINTER pMpi2RaidVolumePhysDisk_t; 210 | 211 | /* defines for the PhysDiskMap field */ 212 | #define MPI2_RAIDACTION_PHYSDISK_PRIMARY (0x01) 213 | #define MPI2_RAIDACTION_PHYSDISK_SECONDARY (0x02) 214 | 215 | typedef struct _MPI2_RAID_VOLUME_CREATION_STRUCT 216 | { 217 | U8 NumPhysDisks; /* 0x00 */ 218 | U8 VolumeType; /* 0x01 */ 219 | U16 Reserved1; /* 0x02 */ 220 | U32 VolumeCreationFlags; /* 0x04 */ 221 | U32 VolumeSettings; /* 0x08 */ 222 | U8 Reserved2; /* 0x0C */ 223 | U8 ResyncRate; /* 0x0D */ 224 | U16 DataScrubDuration; /* 0x0E */ 225 | U64 VolumeMaxLBA; /* 0x10 */ 226 | U32 StripeSize; /* 0x18 */ 227 | U8 Name[16]; /* 0x1C */ 228 | MPI2_RAID_VOLUME_PHYSDISK PhysDisk[MPI2_RAID_VOL_CREATION_NUM_PHYSDISKS];/* 0x2C */ 229 | } MPI2_RAID_VOLUME_CREATION_STRUCT, 230 | MPI2_POINTER PTR_MPI2_RAID_VOLUME_CREATION_STRUCT, 231 | Mpi2RaidVolumeCreationStruct_t, MPI2_POINTER pMpi2RaidVolumeCreationStruct_t; 232 | 233 | /* use MPI2_RAID_VOL_TYPE_ defines from mpi2_cnfg.h for VolumeType */ 234 | 235 | /* defines for the VolumeCreationFlags field */ 236 | #define MPI2_RAID_VOL_CREATION_DEFAULT_SETTINGS (0x80000000) 237 | #define MPI2_RAID_VOL_CREATION_BACKGROUND_INIT (0x00000004) 238 | #define MPI2_RAID_VOL_CREATION_LOW_LEVEL_INIT (0x00000002) 239 | #define MPI2_RAID_VOL_CREATION_MIGRATE_DATA (0x00000001) 240 | /* The following is an obsolete define. 241 | * It must be shifted left 24 bits in order to set the proper bit. 242 | */ 243 | #define MPI2_RAID_VOL_CREATION_USE_DEFAULT_SETTINGS (0x80) 244 | 245 | 246 | /* RAID Online Capacity Expansion Structure */ 247 | 248 | typedef struct _MPI2_RAID_ONLINE_CAPACITY_EXPANSION 249 | { 250 | U32 Flags; /* 0x00 */ 251 | U16 DevHandle0; /* 0x04 */ 252 | U16 Reserved1; /* 0x06 */ 253 | U16 DevHandle1; /* 0x08 */ 254 | U16 Reserved2; /* 0x0A */ 255 | } MPI2_RAID_ONLINE_CAPACITY_EXPANSION, 256 | MPI2_POINTER PTR_MPI2_RAID_ONLINE_CAPACITY_EXPANSION, 257 | Mpi2RaidOnlineCapacityExpansion_t, 258 | MPI2_POINTER pMpi2RaidOnlineCapacityExpansion_t; 259 | 260 | /* RAID Compatibility Input Structure */ 261 | 262 | typedef struct _MPI2_RAID_COMPATIBILITY_INPUT_STRUCT { 263 | U16 SourceDevHandle; /* 0x00 */ 264 | U16 CandidateDevHandle; /* 0x02 */ 265 | U32 Flags; /* 0x04 */ 266 | U32 Reserved1; /* 0x08 */ 267 | U32 Reserved2; /* 0x0C */ 268 | } MPI2_RAID_COMPATIBILITY_INPUT_STRUCT, 269 | MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_INPUT_STRUCT, 270 | Mpi2RaidCompatibilityInputStruct_t, 271 | MPI2_POINTER pMpi2RaidCompatibilityInputStruct_t; 272 | 273 | /* defines for RAID Compatibility Structure Flags field */ 274 | #define MPI2_RAID_COMPAT_SOURCE_IS_VOLUME_FLAG (0x00000002) 275 | #define MPI2_RAID_COMPAT_REPORT_SOURCE_INFO_FLAG (0x00000001) 276 | 277 | 278 | /* RAID Volume Indicator Structure */ 279 | 280 | typedef struct _MPI2_RAID_VOL_INDICATOR 281 | { 282 | U64 TotalBlocks; /* 0x00 */ 283 | U64 BlocksRemaining; /* 0x08 */ 284 | U32 Flags; /* 0x10 */ 285 | U32 ElapsedSeconds; /* 0x14 */ 286 | } MPI2_RAID_VOL_INDICATOR, MPI2_POINTER PTR_MPI2_RAID_VOL_INDICATOR, 287 | Mpi2RaidVolIndicator_t, MPI2_POINTER pMpi2RaidVolIndicator_t; 288 | 289 | /* defines for RAID Volume Indicator Flags field */ 290 | #define MPI2_RAID_VOL_FLAGS_ELAPSED_SECONDS_VALID (0x80000000) 291 | 292 | #define MPI2_RAID_VOL_FLAGS_OP_MASK (0x0000000F) 293 | #define MPI2_RAID_VOL_FLAGS_OP_BACKGROUND_INIT (0x00000000) 294 | #define MPI2_RAID_VOL_FLAGS_OP_ONLINE_CAP_EXPANSION (0x00000001) 295 | #define MPI2_RAID_VOL_FLAGS_OP_CONSISTENCY_CHECK (0x00000002) 296 | #define MPI2_RAID_VOL_FLAGS_OP_RESYNC (0x00000003) 297 | #define MPI2_RAID_VOL_FLAGS_OP_MDC (0x00000004) 298 | 299 | /* RAID Compatibility Result Structure */ 300 | 301 | typedef struct _MPI2_RAID_COMPATIBILITY_RESULT_STRUCT { 302 | U8 State; /* 0x00 */ 303 | U8 Reserved1; /* 0x01 */ 304 | U16 Reserved2; /* 0x02 */ 305 | U32 GenericAttributes; /* 0x04 */ 306 | U32 OEMSpecificAttributes; /* 0x08 */ 307 | U32 Reserved3; /* 0x0C */ 308 | U32 Reserved4; /* 0x10 */ 309 | } MPI2_RAID_COMPATIBILITY_RESULT_STRUCT, 310 | MPI2_POINTER PTR_MPI2_RAID_COMPATIBILITY_RESULT_STRUCT, 311 | Mpi2RaidCompatibilityResultStruct_t, 312 | MPI2_POINTER pMpi2RaidCompatibilityResultStruct_t; 313 | 314 | /* defines for RAID Compatibility Result Structure State field */ 315 | #define MPI2_RAID_COMPAT_STATE_COMPATIBLE (0x00) 316 | #define MPI2_RAID_COMPAT_STATE_NOT_COMPATIBLE (0x01) 317 | 318 | /* defines for RAID Compatibility Result Structure GenericAttributes field */ 319 | #define MPI2_RAID_COMPAT_GENATTRIB_4K_SECTOR (0x00000010) 320 | 321 | #define MPI2_RAID_COMPAT_GENATTRIB_MEDIA_MASK (0x0000000C) 322 | #define MPI2_RAID_COMPAT_GENATTRIB_SOLID_STATE_DRIVE (0x00000008) 323 | #define MPI2_RAID_COMPAT_GENATTRIB_HARD_DISK_DRIVE (0x00000004) 324 | 325 | #define MPI2_RAID_COMPAT_GENATTRIB_PROTOCOL_MASK (0x00000003) 326 | #define MPI2_RAID_COMPAT_GENATTRIB_SAS_PROTOCOL (0x00000002) 327 | #define MPI2_RAID_COMPAT_GENATTRIB_SATA_PROTOCOL (0x00000001) 328 | 329 | /* RAID Action Reply ActionData union */ 330 | typedef union _MPI2_RAID_ACTION_REPLY_DATA 331 | { 332 | U32 Word[6]; 333 | MPI2_RAID_VOL_INDICATOR RaidVolumeIndicator; 334 | U16 VolDevHandle; 335 | U8 VolumeState; 336 | U8 PhysDiskNum; 337 | MPI2_RAID_COMPATIBILITY_RESULT_STRUCT RaidCompatibilityResult; 338 | } MPI2_RAID_ACTION_REPLY_DATA, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY_DATA, 339 | Mpi2RaidActionReplyData_t, MPI2_POINTER pMpi2RaidActionReplyData_t; 340 | 341 | /* use MPI2_RAIDVOL0_SETTING_ defines from mpi2_cnfg.h for MPI2_RAID_ACTION_CHANGE_VOL_WRITE_CACHE action */ 342 | 343 | 344 | /* RAID Action Reply Message */ 345 | typedef struct _MPI2_RAID_ACTION_REPLY 346 | { 347 | U8 Action; /* 0x00 */ 348 | U8 Reserved1; /* 0x01 */ 349 | U8 MsgLength; /* 0x02 */ 350 | U8 Function; /* 0x03 */ 351 | U16 VolDevHandle; /* 0x04 */ 352 | U8 PhysDiskNum; /* 0x06 */ 353 | U8 MsgFlags; /* 0x07 */ 354 | U8 VP_ID; /* 0x08 */ 355 | U8 VF_ID; /* 0x09 */ 356 | U16 Reserved2; /* 0x0A */ 357 | U16 Reserved3; /* 0x0C */ 358 | U16 IOCStatus; /* 0x0E */ 359 | U32 IOCLogInfo; /* 0x10 */ 360 | MPI2_RAID_ACTION_REPLY_DATA ActionData; /* 0x14 */ 361 | } MPI2_RAID_ACTION_REPLY, MPI2_POINTER PTR_MPI2_RAID_ACTION_REPLY, 362 | Mpi2RaidActionReply_t, MPI2_POINTER pMpi2RaidActionReply_t; 363 | 364 | 365 | #endif 366 | 367 | -------------------------------------------------------------------------------- /mpt/mpi/mpi2_sas.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2014 LSI Corporation. 3 | * 4 | * 5 | * Name: mpi2_sas.h 6 | * Title: MPI Serial Attached SCSI structures and definitions 7 | * Creation Date: February 9, 2007 8 | * 9 | * mpi2_sas.h Version: 02.00.05 10 | * 11 | * Version History 12 | * --------------- 13 | * 14 | * Date Version Description 15 | * -------- -------- ------------------------------------------------------ 16 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. 17 | * 06-26-07 02.00.01 Added Clear All Persistent Operation to SAS IO Unit 18 | * Control Request. 19 | * 10-02-08 02.00.02 Added Set IOC Parameter Operation to SAS IO Unit Control 20 | * Request. 21 | * 10-28-09 02.00.03 Changed the type of SGL in MPI2_SATA_PASSTHROUGH_REQUEST 22 | * to MPI2_SGE_IO_UNION since it supports chained SGLs. 23 | * 05-12-10 02.00.04 Modified some comments. 24 | * 08-11-10 02.00.05 Added NCQ operations to SAS IO Unit Control. 25 | * -------------------------------------------------------------------------- 26 | */ 27 | 28 | #ifndef MPI2_SAS_H 29 | #define MPI2_SAS_H 30 | 31 | /* 32 | * Values for SASStatus. 33 | */ 34 | #define MPI2_SASSTATUS_SUCCESS (0x00) 35 | #define MPI2_SASSTATUS_UNKNOWN_ERROR (0x01) 36 | #define MPI2_SASSTATUS_INVALID_FRAME (0x02) 37 | #define MPI2_SASSTATUS_UTC_BAD_DEST (0x03) 38 | #define MPI2_SASSTATUS_UTC_BREAK_RECEIVED (0x04) 39 | #define MPI2_SASSTATUS_UTC_CONNECT_RATE_NOT_SUPPORTED (0x05) 40 | #define MPI2_SASSTATUS_UTC_PORT_LAYER_REQUEST (0x06) 41 | #define MPI2_SASSTATUS_UTC_PROTOCOL_NOT_SUPPORTED (0x07) 42 | #define MPI2_SASSTATUS_UTC_STP_RESOURCES_BUSY (0x08) 43 | #define MPI2_SASSTATUS_UTC_WRONG_DESTINATION (0x09) 44 | #define MPI2_SASSTATUS_SHORT_INFORMATION_UNIT (0x0A) 45 | #define MPI2_SASSTATUS_LONG_INFORMATION_UNIT (0x0B) 46 | #define MPI2_SASSTATUS_XFER_RDY_INCORRECT_WRITE_DATA (0x0C) 47 | #define MPI2_SASSTATUS_XFER_RDY_REQUEST_OFFSET_ERROR (0x0D) 48 | #define MPI2_SASSTATUS_XFER_RDY_NOT_EXPECTED (0x0E) 49 | #define MPI2_SASSTATUS_DATA_INCORRECT_DATA_LENGTH (0x0F) 50 | #define MPI2_SASSTATUS_DATA_TOO_MUCH_READ_DATA (0x10) 51 | #define MPI2_SASSTATUS_DATA_OFFSET_ERROR (0x11) 52 | #define MPI2_SASSTATUS_SDSF_NAK_RECEIVED (0x12) 53 | #define MPI2_SASSTATUS_SDSF_CONNECTION_FAILED (0x13) 54 | #define MPI2_SASSTATUS_INITIATOR_RESPONSE_TIMEOUT (0x14) 55 | 56 | 57 | /* 58 | * Values for the SAS DeviceInfo field used in SAS Device Status Change Event 59 | * data and SAS Configuration pages. 60 | */ 61 | #define MPI2_SAS_DEVICE_INFO_SEP (0x00004000) 62 | #define MPI2_SAS_DEVICE_INFO_ATAPI_DEVICE (0x00002000) 63 | #define MPI2_SAS_DEVICE_INFO_LSI_DEVICE (0x00001000) 64 | #define MPI2_SAS_DEVICE_INFO_DIRECT_ATTACH (0x00000800) 65 | #define MPI2_SAS_DEVICE_INFO_SSP_TARGET (0x00000400) 66 | #define MPI2_SAS_DEVICE_INFO_STP_TARGET (0x00000200) 67 | #define MPI2_SAS_DEVICE_INFO_SMP_TARGET (0x00000100) 68 | #define MPI2_SAS_DEVICE_INFO_SATA_DEVICE (0x00000080) 69 | #define MPI2_SAS_DEVICE_INFO_SSP_INITIATOR (0x00000040) 70 | #define MPI2_SAS_DEVICE_INFO_STP_INITIATOR (0x00000020) 71 | #define MPI2_SAS_DEVICE_INFO_SMP_INITIATOR (0x00000010) 72 | #define MPI2_SAS_DEVICE_INFO_SATA_HOST (0x00000008) 73 | 74 | #define MPI2_SAS_DEVICE_INFO_MASK_DEVICE_TYPE (0x00000007) 75 | #define MPI2_SAS_DEVICE_INFO_NO_DEVICE (0x00000000) 76 | #define MPI2_SAS_DEVICE_INFO_END_DEVICE (0x00000001) 77 | #define MPI2_SAS_DEVICE_INFO_EDGE_EXPANDER (0x00000002) 78 | #define MPI2_SAS_DEVICE_INFO_FANOUT_EXPANDER (0x00000003) 79 | 80 | 81 | /***************************************************************************** 82 | * 83 | * SAS Messages 84 | * 85 | *****************************************************************************/ 86 | 87 | /**************************************************************************** 88 | * SMP Passthrough messages 89 | ****************************************************************************/ 90 | 91 | /* SMP Passthrough Request Message */ 92 | typedef struct _MPI2_SMP_PASSTHROUGH_REQUEST 93 | { 94 | U8 PassthroughFlags; /* 0x00 */ 95 | U8 PhysicalPort; /* 0x01 */ 96 | U8 ChainOffset; /* 0x02 */ 97 | U8 Function; /* 0x03 */ 98 | U16 RequestDataLength; /* 0x04 */ 99 | U8 SGLFlags; /* 0x06 */ 100 | U8 MsgFlags; /* 0x07 */ 101 | U8 VP_ID; /* 0x08 */ 102 | U8 VF_ID; /* 0x09 */ 103 | U16 Reserved1; /* 0x0A */ 104 | U32 Reserved2; /* 0x0C */ 105 | U64 SASAddress; /* 0x10 */ 106 | U32 Reserved3; /* 0x18 */ 107 | U32 Reserved4; /* 0x1C */ 108 | MPI2_SIMPLE_SGE_UNION SGL; /* 0x20 */ 109 | } MPI2_SMP_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REQUEST, 110 | Mpi2SmpPassthroughRequest_t, MPI2_POINTER pMpi2SmpPassthroughRequest_t; 111 | 112 | /* values for PassthroughFlags field */ 113 | #define MPI2_SMP_PT_REQ_PT_FLAGS_IMMEDIATE (0x80) 114 | 115 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ 116 | 117 | 118 | /* SMP Passthrough Reply Message */ 119 | typedef struct _MPI2_SMP_PASSTHROUGH_REPLY 120 | { 121 | U8 PassthroughFlags; /* 0x00 */ 122 | U8 PhysicalPort; /* 0x01 */ 123 | U8 MsgLength; /* 0x02 */ 124 | U8 Function; /* 0x03 */ 125 | U16 ResponseDataLength; /* 0x04 */ 126 | U8 SGLFlags; /* 0x06 */ 127 | U8 MsgFlags; /* 0x07 */ 128 | U8 VP_ID; /* 0x08 */ 129 | U8 VF_ID; /* 0x09 */ 130 | U16 Reserved1; /* 0x0A */ 131 | U8 Reserved2; /* 0x0C */ 132 | U8 SASStatus; /* 0x0D */ 133 | U16 IOCStatus; /* 0x0E */ 134 | U32 IOCLogInfo; /* 0x10 */ 135 | U32 Reserved3; /* 0x14 */ 136 | U8 ResponseData[4]; /* 0x18 */ 137 | } MPI2_SMP_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SMP_PASSTHROUGH_REPLY, 138 | Mpi2SmpPassthroughReply_t, MPI2_POINTER pMpi2SmpPassthroughReply_t; 139 | 140 | /* values for PassthroughFlags field */ 141 | #define MPI2_SMP_PT_REPLY_PT_FLAGS_IMMEDIATE (0x80) 142 | 143 | /* values for SASStatus field are at the top of this file */ 144 | 145 | 146 | /**************************************************************************** 147 | * SATA Passthrough messages 148 | ****************************************************************************/ 149 | 150 | /* SATA Passthrough Request Message */ 151 | typedef struct _MPI2_SATA_PASSTHROUGH_REQUEST 152 | { 153 | U16 DevHandle; /* 0x00 */ 154 | U8 ChainOffset; /* 0x02 */ 155 | U8 Function; /* 0x03 */ 156 | U16 PassthroughFlags; /* 0x04 */ 157 | U8 SGLFlags; /* 0x06 */ 158 | U8 MsgFlags; /* 0x07 */ 159 | U8 VP_ID; /* 0x08 */ 160 | U8 VF_ID; /* 0x09 */ 161 | U16 Reserved1; /* 0x0A */ 162 | U32 Reserved2; /* 0x0C */ 163 | U32 Reserved3; /* 0x10 */ 164 | U32 Reserved4; /* 0x14 */ 165 | U32 DataLength; /* 0x18 */ 166 | U8 CommandFIS[20]; /* 0x1C */ 167 | MPI2_SGE_IO_UNION SGL; /* 0x30 */ 168 | } MPI2_SATA_PASSTHROUGH_REQUEST, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REQUEST, 169 | Mpi2SataPassthroughRequest_t, MPI2_POINTER pMpi2SataPassthroughRequest_t; 170 | 171 | /* values for PassthroughFlags field */ 172 | #define MPI2_SATA_PT_REQ_PT_FLAGS_EXECUTE_DIAG (0x0100) 173 | #define MPI2_SATA_PT_REQ_PT_FLAGS_DMA (0x0020) 174 | #define MPI2_SATA_PT_REQ_PT_FLAGS_PIO (0x0010) 175 | #define MPI2_SATA_PT_REQ_PT_FLAGS_UNSPECIFIED_VU (0x0004) 176 | #define MPI2_SATA_PT_REQ_PT_FLAGS_WRITE (0x0002) 177 | #define MPI2_SATA_PT_REQ_PT_FLAGS_READ (0x0001) 178 | 179 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ 180 | 181 | 182 | /* SATA Passthrough Reply Message */ 183 | typedef struct _MPI2_SATA_PASSTHROUGH_REPLY 184 | { 185 | U16 DevHandle; /* 0x00 */ 186 | U8 MsgLength; /* 0x02 */ 187 | U8 Function; /* 0x03 */ 188 | U16 PassthroughFlags; /* 0x04 */ 189 | U8 SGLFlags; /* 0x06 */ 190 | U8 MsgFlags; /* 0x07 */ 191 | U8 VP_ID; /* 0x08 */ 192 | U8 VF_ID; /* 0x09 */ 193 | U16 Reserved1; /* 0x0A */ 194 | U8 Reserved2; /* 0x0C */ 195 | U8 SASStatus; /* 0x0D */ 196 | U16 IOCStatus; /* 0x0E */ 197 | U32 IOCLogInfo; /* 0x10 */ 198 | U8 StatusFIS[20]; /* 0x14 */ 199 | U32 StatusControlRegisters; /* 0x28 */ 200 | U32 TransferCount; /* 0x2C */ 201 | } MPI2_SATA_PASSTHROUGH_REPLY, MPI2_POINTER PTR_MPI2_SATA_PASSTHROUGH_REPLY, 202 | Mpi2SataPassthroughReply_t, MPI2_POINTER pMpi2SataPassthroughReply_t; 203 | 204 | /* values for SASStatus field are at the top of this file */ 205 | 206 | 207 | /**************************************************************************** 208 | * SAS IO Unit Control messages 209 | ****************************************************************************/ 210 | 211 | /* SAS IO Unit Control Request Message */ 212 | typedef struct _MPI2_SAS_IOUNIT_CONTROL_REQUEST 213 | { 214 | U8 Operation; /* 0x00 */ 215 | U8 Reserved1; /* 0x01 */ 216 | U8 ChainOffset; /* 0x02 */ 217 | U8 Function; /* 0x03 */ 218 | U16 DevHandle; /* 0x04 */ 219 | U8 IOCParameter; /* 0x06 */ 220 | U8 MsgFlags; /* 0x07 */ 221 | U8 VP_ID; /* 0x08 */ 222 | U8 VF_ID; /* 0x09 */ 223 | U16 Reserved3; /* 0x0A */ 224 | U16 Reserved4; /* 0x0C */ 225 | U8 PhyNum; /* 0x0E */ 226 | U8 PrimFlags; /* 0x0F */ 227 | U32 Primitive; /* 0x10 */ 228 | U8 LookupMethod; /* 0x14 */ 229 | U8 Reserved5; /* 0x15 */ 230 | U16 SlotNumber; /* 0x16 */ 231 | U64 LookupAddress; /* 0x18 */ 232 | U32 IOCParameterValue; /* 0x20 */ 233 | U32 Reserved7; /* 0x24 */ 234 | U32 Reserved8; /* 0x28 */ 235 | } MPI2_SAS_IOUNIT_CONTROL_REQUEST, 236 | MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REQUEST, 237 | Mpi2SasIoUnitControlRequest_t, MPI2_POINTER pMpi2SasIoUnitControlRequest_t; 238 | 239 | /* values for the Operation field */ 240 | #define MPI2_SAS_OP_CLEAR_ALL_PERSISTENT (0x02) 241 | #define MPI2_SAS_OP_PHY_LINK_RESET (0x06) 242 | #define MPI2_SAS_OP_PHY_HARD_RESET (0x07) 243 | #define MPI2_SAS_OP_PHY_CLEAR_ERROR_LOG (0x08) 244 | #define MPI2_SAS_OP_SEND_PRIMITIVE (0x0A) 245 | #define MPI2_SAS_OP_FORCE_FULL_DISCOVERY (0x0B) 246 | #define MPI2_SAS_OP_TRANSMIT_PORT_SELECT_SIGNAL (0x0C) 247 | #define MPI2_SAS_OP_REMOVE_DEVICE (0x0D) 248 | #define MPI2_SAS_OP_LOOKUP_MAPPING (0x0E) 249 | #define MPI2_SAS_OP_SET_IOC_PARAMETER (0x0F) 250 | #define MPI2_SAS_OP_DEV_ENABLE_NCQ (0x14) 251 | #define MPI2_SAS_OP_DEV_DISABLE_NCQ (0x15) 252 | #define MPI2_SAS_OP_PRODUCT_SPECIFIC_MIN (0x80) 253 | 254 | /* values for the PrimFlags field */ 255 | #define MPI2_SAS_PRIMFLAGS_SINGLE (0x08) 256 | #define MPI2_SAS_PRIMFLAGS_TRIPLE (0x02) 257 | #define MPI2_SAS_PRIMFLAGS_REDUNDANT (0x01) 258 | 259 | /* values for the LookupMethod field */ 260 | #define MPI2_SAS_LOOKUP_METHOD_SAS_ADDRESS (0x01) 261 | #define MPI2_SAS_LOOKUP_METHOD_SAS_ENCLOSURE_SLOT (0x02) 262 | #define MPI2_SAS_LOOKUP_METHOD_SAS_DEVICE_NAME (0x03) 263 | 264 | 265 | /* SAS IO Unit Control Reply Message */ 266 | typedef struct _MPI2_SAS_IOUNIT_CONTROL_REPLY 267 | { 268 | U8 Operation; /* 0x00 */ 269 | U8 Reserved1; /* 0x01 */ 270 | U8 MsgLength; /* 0x02 */ 271 | U8 Function; /* 0x03 */ 272 | U16 DevHandle; /* 0x04 */ 273 | U8 IOCParameter; /* 0x06 */ 274 | U8 MsgFlags; /* 0x07 */ 275 | U8 VP_ID; /* 0x08 */ 276 | U8 VF_ID; /* 0x09 */ 277 | U16 Reserved3; /* 0x0A */ 278 | U16 Reserved4; /* 0x0C */ 279 | U16 IOCStatus; /* 0x0E */ 280 | U32 IOCLogInfo; /* 0x10 */ 281 | } MPI2_SAS_IOUNIT_CONTROL_REPLY, 282 | MPI2_POINTER PTR_MPI2_SAS_IOUNIT_CONTROL_REPLY, 283 | Mpi2SasIoUnitControlReply_t, MPI2_POINTER pMpi2SasIoUnitControlReply_t; 284 | 285 | 286 | #endif 287 | 288 | 289 | -------------------------------------------------------------------------------- /mpt/mpi/mpi2_tool.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2014 LSI Corporation. 3 | * 4 | * 5 | * Name: mpi2_tool.h 6 | * Title: MPI diagnostic tool structures and definitions 7 | * Creation Date: March 26, 2007 8 | * 9 | * mpi2_tool.h Version: 02.00.12 10 | * 11 | * Version History 12 | * --------------- 13 | * 14 | * Date Version Description 15 | * -------- -------- ------------------------------------------------------ 16 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. 17 | * 12-18-07 02.00.01 Added Diagnostic Buffer Post and Diagnostic Release 18 | * structures and defines. 19 | * 02-29-08 02.00.02 Modified various names to make them 32-character unique. 20 | * 05-06-09 02.00.03 Added ISTWI Read Write Tool and Diagnostic CLI Tool. 21 | * 07-30-09 02.00.04 Added ExtendedType field to DiagnosticBufferPost request 22 | * and reply messages. 23 | * Added MPI2_DIAG_BUF_TYPE_EXTENDED. 24 | * Incremented MPI2_DIAG_BUF_TYPE_COUNT. 25 | * 05-12-10 02.00.05 Added Diagnostic Data Upload tool. 26 | * 08-11-10 02.00.06 Added defines that were missing for Diagnostic Buffer 27 | * Post Request. 28 | * 05-25-11 02.00.07 Added Flags field and related defines to 29 | * MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST. 30 | * 07-26-12 02.00.10 Modified MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST so that 31 | * it uses MPI Chain SGE as well as MPI Simple SGE. 32 | * 08-19-13 02.00.11 Added MPI2_TOOLBOX_TEXT_DISPLAY_TOOL and related info. 33 | * 01-08-14 02.00.12 Added MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC. 34 | * -------------------------------------------------------------------------- 35 | */ 36 | 37 | #ifndef MPI2_TOOL_H 38 | #define MPI2_TOOL_H 39 | 40 | /***************************************************************************** 41 | * 42 | * Toolbox Messages 43 | * 44 | *****************************************************************************/ 45 | 46 | /* defines for the Tools */ 47 | #define MPI2_TOOLBOX_CLEAN_TOOL (0x00) 48 | #define MPI2_TOOLBOX_MEMORY_MOVE_TOOL (0x01) 49 | #define MPI2_TOOLBOX_DIAG_DATA_UPLOAD_TOOL (0x02) 50 | #define MPI2_TOOLBOX_ISTWI_READ_WRITE_TOOL (0x03) 51 | #define MPI2_TOOLBOX_BEACON_TOOL (0x05) 52 | #define MPI2_TOOLBOX_DIAGNOSTIC_CLI_TOOL (0x06) 53 | #define MPI2_TOOLBOX_TEXT_DISPLAY_TOOL (0x07) 54 | 55 | 56 | /**************************************************************************** 57 | * Toolbox reply 58 | ****************************************************************************/ 59 | 60 | typedef struct _MPI2_TOOLBOX_REPLY 61 | { 62 | U8 Tool; /* 0x00 */ 63 | U8 Reserved1; /* 0x01 */ 64 | U8 MsgLength; /* 0x02 */ 65 | U8 Function; /* 0x03 */ 66 | U16 Reserved2; /* 0x04 */ 67 | U8 Reserved3; /* 0x06 */ 68 | U8 MsgFlags; /* 0x07 */ 69 | U8 VP_ID; /* 0x08 */ 70 | U8 VF_ID; /* 0x09 */ 71 | U16 Reserved4; /* 0x0A */ 72 | U16 Reserved5; /* 0x0C */ 73 | U16 IOCStatus; /* 0x0E */ 74 | U32 IOCLogInfo; /* 0x10 */ 75 | } MPI2_TOOLBOX_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_REPLY, 76 | Mpi2ToolboxReply_t, MPI2_POINTER pMpi2ToolboxReply_t; 77 | 78 | 79 | /**************************************************************************** 80 | * Toolbox Clean Tool request 81 | ****************************************************************************/ 82 | 83 | typedef struct _MPI2_TOOLBOX_CLEAN_REQUEST 84 | { 85 | U8 Tool; /* 0x00 */ 86 | U8 Reserved1; /* 0x01 */ 87 | U8 ChainOffset; /* 0x02 */ 88 | U8 Function; /* 0x03 */ 89 | U16 Reserved2; /* 0x04 */ 90 | U8 Reserved3; /* 0x06 */ 91 | U8 MsgFlags; /* 0x07 */ 92 | U8 VP_ID; /* 0x08 */ 93 | U8 VF_ID; /* 0x09 */ 94 | U16 Reserved4; /* 0x0A */ 95 | U32 Flags; /* 0x0C */ 96 | } MPI2_TOOLBOX_CLEAN_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_CLEAN_REQUEST, 97 | Mpi2ToolboxCleanRequest_t, MPI2_POINTER pMpi2ToolboxCleanRequest_t; 98 | 99 | /* values for the Flags field */ 100 | #define MPI2_TOOLBOX_CLEAN_BOOT_SERVICES (0x80000000) 101 | #define MPI2_TOOLBOX_CLEAN_PERSIST_MANUFACT_PAGES (0x40000000) 102 | #define MPI2_TOOLBOX_CLEAN_OTHER_PERSIST_PAGES (0x20000000) 103 | #define MPI2_TOOLBOX_CLEAN_FW_CURRENT (0x10000000) 104 | #define MPI2_TOOLBOX_CLEAN_FW_BACKUP (0x08000000) 105 | #define MPI2_TOOLBOX_CLEAN_BIT26_PRODUCT_SPECIFIC (0x04000000) 106 | #define MPI2_TOOLBOX_CLEAN_MEGARAID (0x02000000) 107 | #define MPI2_TOOLBOX_CLEAN_INITIALIZATION (0x01000000) 108 | #define MPI2_TOOLBOX_CLEAN_FLASH (0x00000004) 109 | #define MPI2_TOOLBOX_CLEAN_SEEPROM (0x00000002) 110 | #define MPI2_TOOLBOX_CLEAN_NVSRAM (0x00000001) 111 | 112 | 113 | /**************************************************************************** 114 | * Toolbox Memory Move request 115 | ****************************************************************************/ 116 | 117 | typedef struct _MPI2_TOOLBOX_MEM_MOVE_REQUEST { 118 | U8 Tool; /* 0x00 */ 119 | U8 Reserved1; /* 0x01 */ 120 | U8 ChainOffset; /* 0x02 */ 121 | U8 Function; /* 0x03 */ 122 | U16 Reserved2; /* 0x04 */ 123 | U8 Reserved3; /* 0x06 */ 124 | U8 MsgFlags; /* 0x07 */ 125 | U8 VP_ID; /* 0x08 */ 126 | U8 VF_ID; /* 0x09 */ 127 | U16 Reserved4; /* 0x0A */ 128 | MPI2_SGE_SIMPLE_UNION SGL; /* 0x0C */ 129 | } MPI2_TOOLBOX_MEM_MOVE_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_MEM_MOVE_REQUEST, 130 | Mpi2ToolboxMemMoveRequest_t, MPI2_POINTER pMpi2ToolboxMemMoveRequest_t; 131 | 132 | 133 | /**************************************************************************** 134 | * Toolbox Diagnostic Data Upload request 135 | ****************************************************************************/ 136 | 137 | typedef struct _MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST { 138 | U8 Tool; /* 0x00 */ 139 | U8 Reserved1; /* 0x01 */ 140 | U8 ChainOffset; /* 0x02 */ 141 | U8 Function; /* 0x03 */ 142 | U16 Reserved2; /* 0x04 */ 143 | U8 Reserved3; /* 0x06 */ 144 | U8 MsgFlags; /* 0x07 */ 145 | U8 VP_ID; /* 0x08 */ 146 | U8 VF_ID; /* 0x09 */ 147 | U16 Reserved4; /* 0x0A */ 148 | U8 SGLFlags; /* 0x0C */ 149 | U8 Reserved5; /* 0x0D */ 150 | U16 Reserved6; /* 0x0E */ 151 | U32 Flags; /* 0x10 */ 152 | U32 DataLength; /* 0x14 */ 153 | MPI2_SGE_SIMPLE_UNION SGL; /* 0x18 */ 154 | } MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, 155 | MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_DATA_UPLOAD_REQUEST, 156 | Mpi2ToolboxDiagDataUploadRequest_t, 157 | MPI2_POINTER pMpi2ToolboxDiagDataUploadRequest_t; 158 | 159 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ 160 | 161 | 162 | typedef struct _MPI2_DIAG_DATA_UPLOAD_HEADER { 163 | U32 DiagDataLength; /* 00h */ 164 | U8 FormatCode; /* 04h */ 165 | U8 Reserved1; /* 05h */ 166 | U16 Reserved2; /* 06h */ 167 | } MPI2_DIAG_DATA_UPLOAD_HEADER, MPI2_POINTER PTR_MPI2_DIAG_DATA_UPLOAD_HEADER, 168 | Mpi2DiagDataUploadHeader_t, MPI2_POINTER pMpi2DiagDataUploadHeader_t; 169 | 170 | 171 | /**************************************************************************** 172 | * Toolbox ISTWI Read Write Tool 173 | ****************************************************************************/ 174 | 175 | /* Toolbox ISTWI Read Write Tool request message */ 176 | typedef struct _MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST { 177 | U8 Tool; /* 0x00 */ 178 | U8 Reserved1; /* 0x01 */ 179 | U8 ChainOffset; /* 0x02 */ 180 | U8 Function; /* 0x03 */ 181 | U16 Reserved2; /* 0x04 */ 182 | U8 Reserved3; /* 0x06 */ 183 | U8 MsgFlags; /* 0x07 */ 184 | U8 VP_ID; /* 0x08 */ 185 | U8 VF_ID; /* 0x09 */ 186 | U16 Reserved4; /* 0x0A */ 187 | U32 Reserved5; /* 0x0C */ 188 | U32 Reserved6; /* 0x10 */ 189 | U8 DevIndex; /* 0x14 */ 190 | U8 Action; /* 0x15 */ 191 | U8 SGLFlags; /* 0x16 */ 192 | U8 Flags; /* 0x17 */ 193 | U16 TxDataLength; /* 0x18 */ 194 | U16 RxDataLength; /* 0x1A */ 195 | U32 Reserved8; /* 0x1C */ 196 | U32 Reserved9; /* 0x20 */ 197 | U32 Reserved10; /* 0x24 */ 198 | U32 Reserved11; /* 0x28 */ 199 | U32 Reserved12; /* 0x2C */ 200 | MPI2_SGE_SIMPLE_UNION SGL; /* 0x30 */ 201 | } MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, 202 | MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_READ_WRITE_REQUEST, 203 | Mpi2ToolboxIstwiReadWriteRequest_t, 204 | MPI2_POINTER pMpi2ToolboxIstwiReadWriteRequest_t; 205 | 206 | /* values for the Action field */ 207 | #define MPI2_TOOL_ISTWI_ACTION_READ_DATA (0x01) 208 | #define MPI2_TOOL_ISTWI_ACTION_WRITE_DATA (0x02) 209 | #define MPI2_TOOL_ISTWI_ACTION_SEQUENCE (0x03) 210 | #define MPI2_TOOL_ISTWI_ACTION_RESERVE_BUS (0x10) 211 | #define MPI2_TOOL_ISTWI_ACTION_RELEASE_BUS (0x11) 212 | #define MPI2_TOOL_ISTWI_ACTION_RESET (0x12) 213 | 214 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ 215 | 216 | /* values for the Flags field */ 217 | #define MPI2_TOOL_ISTWI_FLAG_AUTO_RESERVE_RELEASE (0x80) 218 | #define MPI2_TOOL_ISTWI_FLAG_PAGE_ADDR_MASK (0x07) 219 | 220 | /* Toolbox ISTWI Read Write Tool reply message */ 221 | typedef struct _MPI2_TOOLBOX_ISTWI_REPLY { 222 | U8 Tool; /* 0x00 */ 223 | U8 Reserved1; /* 0x01 */ 224 | U8 MsgLength; /* 0x02 */ 225 | U8 Function; /* 0x03 */ 226 | U16 Reserved2; /* 0x04 */ 227 | U8 Reserved3; /* 0x06 */ 228 | U8 MsgFlags; /* 0x07 */ 229 | U8 VP_ID; /* 0x08 */ 230 | U8 VF_ID; /* 0x09 */ 231 | U16 Reserved4; /* 0x0A */ 232 | U16 Reserved5; /* 0x0C */ 233 | U16 IOCStatus; /* 0x0E */ 234 | U32 IOCLogInfo; /* 0x10 */ 235 | U8 DevIndex; /* 0x14 */ 236 | U8 Action; /* 0x15 */ 237 | U8 IstwiStatus; /* 0x16 */ 238 | U8 Reserved6; /* 0x17 */ 239 | U16 TxDataCount; /* 0x18 */ 240 | U16 RxDataCount; /* 0x1A */ 241 | } MPI2_TOOLBOX_ISTWI_REPLY, MPI2_POINTER PTR_MPI2_TOOLBOX_ISTWI_REPLY, 242 | Mpi2ToolboxIstwiReply_t, MPI2_POINTER pMpi2ToolboxIstwiReply_t; 243 | 244 | 245 | /**************************************************************************** 246 | * Toolbox Beacon Tool request 247 | ****************************************************************************/ 248 | 249 | typedef struct _MPI2_TOOLBOX_BEACON_REQUEST 250 | { 251 | U8 Tool; /* 0x00 */ 252 | U8 Reserved1; /* 0x01 */ 253 | U8 ChainOffset; /* 0x02 */ 254 | U8 Function; /* 0x03 */ 255 | U16 Reserved2; /* 0x04 */ 256 | U8 Reserved3; /* 0x06 */ 257 | U8 MsgFlags; /* 0x07 */ 258 | U8 VP_ID; /* 0x08 */ 259 | U8 VF_ID; /* 0x09 */ 260 | U16 Reserved4; /* 0x0A */ 261 | U8 Reserved5; /* 0x0C */ 262 | U8 PhysicalPort; /* 0x0D */ 263 | U8 Reserved6; /* 0x0E */ 264 | U8 Flags; /* 0x0F */ 265 | } MPI2_TOOLBOX_BEACON_REQUEST, MPI2_POINTER PTR_MPI2_TOOLBOX_BEACON_REQUEST, 266 | Mpi2ToolboxBeaconRequest_t, MPI2_POINTER pMpi2ToolboxBeaconRequest_t; 267 | 268 | /* values for the Flags field */ 269 | #define MPI2_TOOLBOX_FLAGS_BEACONMODE_OFF (0x00) 270 | #define MPI2_TOOLBOX_FLAGS_BEACONMODE_ON (0x01) 271 | 272 | 273 | /**************************************************************************** 274 | * Toolbox Diagnostic CLI Tool 275 | ****************************************************************************/ 276 | 277 | #define MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH (0x5C) 278 | 279 | /* MPI v2.0 Toolbox Diagnostic CLI Tool request message */ 280 | typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST { 281 | U8 Tool; /* 0x00 */ 282 | U8 Reserved1; /* 0x01 */ 283 | U8 ChainOffset; /* 0x02 */ 284 | U8 Function; /* 0x03 */ 285 | U16 Reserved2; /* 0x04 */ 286 | U8 Reserved3; /* 0x06 */ 287 | U8 MsgFlags; /* 0x07 */ 288 | U8 VP_ID; /* 0x08 */ 289 | U8 VF_ID; /* 0x09 */ 290 | U16 Reserved4; /* 0x0A */ 291 | U8 SGLFlags; /* 0x0C */ 292 | U8 Reserved5; /* 0x0D */ 293 | U16 Reserved6; /* 0x0E */ 294 | U32 DataLength; /* 0x10 */ 295 | U8 DiagnosticCliCommand 296 | [MPI2_TOOLBOX_DIAG_CLI_CMD_LENGTH]; /* 0x14 */ 297 | MPI2_MPI_SGE_IO_UNION SGL; /* 0x70 */ 298 | } MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, 299 | MPI2_POINTER PTR_MPI2_TOOLBOX_DIAGNOSTIC_CLI_REQUEST, 300 | Mpi2ToolboxDiagnosticCliRequest_t, 301 | MPI2_POINTER pMpi2ToolboxDiagnosticCliRequest_t; 302 | 303 | /* use MPI2_SGLFLAGS_ defines from mpi2.h for the SGLFlags field */ 304 | 305 | 306 | /* Toolbox Diagnostic CLI Tool reply message */ 307 | typedef struct _MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY { 308 | U8 Tool; /* 0x00 */ 309 | U8 Reserved1; /* 0x01 */ 310 | U8 MsgLength; /* 0x02 */ 311 | U8 Function; /* 0x03 */ 312 | U16 Reserved2; /* 0x04 */ 313 | U8 Reserved3; /* 0x06 */ 314 | U8 MsgFlags; /* 0x07 */ 315 | U8 VP_ID; /* 0x08 */ 316 | U8 VF_ID; /* 0x09 */ 317 | U16 Reserved4; /* 0x0A */ 318 | U16 Reserved5; /* 0x0C */ 319 | U16 IOCStatus; /* 0x0E */ 320 | U32 IOCLogInfo; /* 0x10 */ 321 | U32 ReturnedDataLength; /* 0x14 */ 322 | } MPI2_TOOLBOX_DIAGNOSTIC_CLI_REPLY, 323 | MPI2_POINTER PTR_MPI2_TOOLBOX_DIAG_CLI_REPLY, 324 | Mpi2ToolboxDiagnosticCliReply_t, 325 | MPI2_POINTER pMpi2ToolboxDiagnosticCliReply_t; 326 | 327 | 328 | /**************************************************************************** 329 | * Toolbox Console Text Display Tool 330 | ****************************************************************************/ 331 | 332 | /* Toolbox Console Text Display Tool request message */ 333 | typedef struct _MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST { 334 | U8 Tool; /* 0x00 */ 335 | U8 Reserved1; /* 0x01 */ 336 | U8 ChainOffset; /* 0x02 */ 337 | U8 Function; /* 0x03 */ 338 | U16 Reserved2; /* 0x04 */ 339 | U8 Reserved3; /* 0x06 */ 340 | U8 MsgFlags; /* 0x07 */ 341 | U8 VP_ID; /* 0x08 */ 342 | U8 VF_ID; /* 0x09 */ 343 | U16 Reserved4; /* 0x0A */ 344 | U8 Console; /* 0x0C */ 345 | U8 Flags; /* 0x0D */ 346 | U16 Reserved6; /* 0x0E */ 347 | U8 TextToDisplay[4]; /* 0x10 */ 348 | } MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, 349 | MPI2_POINTER PTR_MPI2_TOOLBOX_TEXT_DISPLAY_REQUEST, 350 | Mpi2ToolboxTextDisplayRequest_t, 351 | MPI2_POINTER pMpi2ToolboxTextDisplayRequest_t; 352 | 353 | /* defines for the Console field */ 354 | #define MPI2_TOOLBOX_CONSOLE_TYPE_MASK (0xF0) 355 | #define MPI2_TOOLBOX_CONSOLE_TYPE_DEFAULT (0x00) 356 | #define MPI2_TOOLBOX_CONSOLE_TYPE_UART (0x10) 357 | #define MPI2_TOOLBOX_CONSOLE_TYPE_ETHERNET (0x20) 358 | 359 | #define MPI2_TOOLBOX_CONSOLE_NUMBER_MASK (0x0F) 360 | 361 | /* defines for the Flags field */ 362 | #define MPI2_TOOLBOX_CONSOLE_FLAG_TIMESTAMP (0x01) 363 | 364 | 365 | 366 | /***************************************************************************** 367 | * 368 | * Diagnostic Buffer Messages 369 | * 370 | *****************************************************************************/ 371 | 372 | 373 | /**************************************************************************** 374 | * Diagnostic Buffer Post request 375 | ****************************************************************************/ 376 | 377 | typedef struct _MPI2_DIAG_BUFFER_POST_REQUEST 378 | { 379 | U8 ExtendedType; /* 0x00 */ 380 | U8 BufferType; /* 0x01 */ 381 | U8 ChainOffset; /* 0x02 */ 382 | U8 Function; /* 0x03 */ 383 | U16 Reserved2; /* 0x04 */ 384 | U8 Reserved3; /* 0x06 */ 385 | U8 MsgFlags; /* 0x07 */ 386 | U8 VP_ID; /* 0x08 */ 387 | U8 VF_ID; /* 0x09 */ 388 | U16 Reserved4; /* 0x0A */ 389 | U64 BufferAddress; /* 0x0C */ 390 | U32 BufferLength; /* 0x14 */ 391 | U32 Reserved5; /* 0x18 */ 392 | U32 Reserved6; /* 0x1C */ 393 | U32 Flags; /* 0x20 */ 394 | U32 ProductSpecific[23]; /* 0x24 */ 395 | } MPI2_DIAG_BUFFER_POST_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REQUEST, 396 | Mpi2DiagBufferPostRequest_t, MPI2_POINTER pMpi2DiagBufferPostRequest_t; 397 | 398 | /* values for the ExtendedType field */ 399 | #define MPI2_DIAG_EXTENDED_TYPE_UTILIZATION (0x02) 400 | 401 | /* values for the BufferType field */ 402 | #define MPI2_DIAG_BUF_TYPE_TRACE (0x00) 403 | #define MPI2_DIAG_BUF_TYPE_SNAPSHOT (0x01) 404 | #define MPI2_DIAG_BUF_TYPE_EXTENDED (0x02) 405 | /* count of the number of buffer types */ 406 | #define MPI2_DIAG_BUF_TYPE_COUNT (0x03) 407 | 408 | /* values for the Flags field */ 409 | #define MPI2_DIAG_BUF_FLAG_RELEASE_ON_FULL (0x00000002) 410 | #define MPI2_DIAG_BUF_FLAG_IMMEDIATE_RELEASE (0x00000001) 411 | 412 | 413 | /**************************************************************************** 414 | * Diagnostic Buffer Post reply 415 | ****************************************************************************/ 416 | 417 | typedef struct _MPI2_DIAG_BUFFER_POST_REPLY 418 | { 419 | U8 ExtendedType; /* 0x00 */ 420 | U8 BufferType; /* 0x01 */ 421 | U8 MsgLength; /* 0x02 */ 422 | U8 Function; /* 0x03 */ 423 | U16 Reserved2; /* 0x04 */ 424 | U8 Reserved3; /* 0x06 */ 425 | U8 MsgFlags; /* 0x07 */ 426 | U8 VP_ID; /* 0x08 */ 427 | U8 VF_ID; /* 0x09 */ 428 | U16 Reserved4; /* 0x0A */ 429 | U16 Reserved5; /* 0x0C */ 430 | U16 IOCStatus; /* 0x0E */ 431 | U32 IOCLogInfo; /* 0x10 */ 432 | U32 TransferLength; /* 0x14 */ 433 | } MPI2_DIAG_BUFFER_POST_REPLY, MPI2_POINTER PTR_MPI2_DIAG_BUFFER_POST_REPLY, 434 | Mpi2DiagBufferPostReply_t, MPI2_POINTER pMpi2DiagBufferPostReply_t; 435 | 436 | 437 | /**************************************************************************** 438 | * Diagnostic Release request 439 | ****************************************************************************/ 440 | 441 | typedef struct _MPI2_DIAG_RELEASE_REQUEST 442 | { 443 | U8 Reserved1; /* 0x00 */ 444 | U8 BufferType; /* 0x01 */ 445 | U8 ChainOffset; /* 0x02 */ 446 | U8 Function; /* 0x03 */ 447 | U16 Reserved2; /* 0x04 */ 448 | U8 Reserved3; /* 0x06 */ 449 | U8 MsgFlags; /* 0x07 */ 450 | U8 VP_ID; /* 0x08 */ 451 | U8 VF_ID; /* 0x09 */ 452 | U16 Reserved4; /* 0x0A */ 453 | } MPI2_DIAG_RELEASE_REQUEST, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REQUEST, 454 | Mpi2DiagReleaseRequest_t, MPI2_POINTER pMpi2DiagReleaseRequest_t; 455 | 456 | 457 | /**************************************************************************** 458 | * Diagnostic Buffer Post reply 459 | ****************************************************************************/ 460 | 461 | typedef struct _MPI2_DIAG_RELEASE_REPLY 462 | { 463 | U8 Reserved1; /* 0x00 */ 464 | U8 BufferType; /* 0x01 */ 465 | U8 MsgLength; /* 0x02 */ 466 | U8 Function; /* 0x03 */ 467 | U16 Reserved2; /* 0x04 */ 468 | U8 Reserved3; /* 0x06 */ 469 | U8 MsgFlags; /* 0x07 */ 470 | U8 VP_ID; /* 0x08 */ 471 | U8 VF_ID; /* 0x09 */ 472 | U16 Reserved4; /* 0x0A */ 473 | U16 Reserved5; /* 0x0C */ 474 | U16 IOCStatus; /* 0x0E */ 475 | U32 IOCLogInfo; /* 0x10 */ 476 | } MPI2_DIAG_RELEASE_REPLY, MPI2_POINTER PTR_MPI2_DIAG_RELEASE_REPLY, 477 | Mpi2DiagReleaseReply_t, MPI2_POINTER pMpi2DiagReleaseReply_t; 478 | 479 | 480 | #endif 481 | 482 | -------------------------------------------------------------------------------- /mpt/mpi/mpi2_type.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2014 LSI Corporation. 3 | * 4 | * 5 | * Name: mpi2_type.h 6 | * Title: MPI basic type definitions 7 | * Creation Date: August 16, 2006 8 | * 9 | * mpi2_type.h Version: 02.00.00 10 | * 11 | * Version History 12 | * --------------- 13 | * 14 | * Date Version Description 15 | * -------- -------- ------------------------------------------------------ 16 | * 04-30-07 02.00.00 Corresponds to Fusion-MPT MPI Specification Rev A. 17 | * -------------------------------------------------------------------------- 18 | */ 19 | 20 | #ifndef MPI2_TYPE_H 21 | #define MPI2_TYPE_H 22 | 23 | 24 | /******************************************************************************* 25 | * Define MPI2_POINTER if it hasn't already been defined. By default 26 | * MPI2_POINTER is defined to be a near pointer. MPI2_POINTER can be defined as 27 | * a far pointer by defining MPI2_POINTER as "far *" before this header file is 28 | * included. 29 | */ 30 | #ifndef MPI2_POINTER 31 | #define MPI2_POINTER * 32 | #endif 33 | 34 | /* the basic types may have already been included by mpi_type.h */ 35 | #ifndef MPI_TYPE_H 36 | /***************************************************************************** 37 | * 38 | * Basic Types 39 | * 40 | *****************************************************************************/ 41 | 42 | typedef u8 U8; 43 | typedef __le16 U16; 44 | typedef __le32 U32; 45 | typedef __le64 U64 __attribute__((aligned(4))); 46 | 47 | /***************************************************************************** 48 | * 49 | * Pointer Types 50 | * 51 | *****************************************************************************/ 52 | 53 | typedef U8 *PU8; 54 | typedef U16 *PU16; 55 | typedef U32 *PU32; 56 | typedef U64 *PU64; 57 | 58 | #endif 59 | 60 | #endif 61 | 62 | -------------------------------------------------------------------------------- /mpt/mpt2sas_ctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Management Module Support for MPT (Message Passing Technology) based 3 | * controllers 4 | * 5 | * This code is based on drivers/scsi/mpt2sas/mpt2_ctl.h 6 | * Copyright (C) 2007-2013 LSI Corporation 7 | * (mailto:DL-MPTFusionLinux@lsi.com) 8 | * 9 | * This program is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU General Public License 11 | * as published by the Free Software Foundation; either version 2 12 | * of the License, or (at your option) any later version. 13 | * 14 | * This program is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | * GNU General Public License for more details. 18 | * 19 | * NO WARRANTY 20 | * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 21 | * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 22 | * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 23 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 24 | * solely responsible for determining the appropriateness of using and 25 | * distributing the Program and assumes all risks associated with its 26 | * exercise of rights under this Agreement, including but not limited to 27 | * the risks and costs of program errors, damage to or loss of data, 28 | * programs or equipment, and unavailability or interruption of operations. 29 | 30 | * DISCLAIMER OF LIABILITY 31 | * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 32 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 | * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 34 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 36 | * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 37 | * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 38 | 39 | * You should have received a copy of the GNU General Public License 40 | * along with this program; if not, write to the Free Software 41 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 42 | * USA. 43 | */ 44 | 45 | #ifndef MPT2SAS_CTL_H_INCLUDED 46 | #define MPT2SAS_CTL_H_INCLUDED 47 | 48 | #ifdef __KERNEL__ 49 | #include 50 | #endif 51 | 52 | #define MPT2SAS_DEV_NAME "mpt2ctl" 53 | #define MPT2_MAGIC_NUMBER 'L' 54 | #define MPT2_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */ 55 | 56 | /** 57 | * IOCTL opcodes 58 | */ 59 | #define MPT2IOCINFO _IOWR(MPT2_MAGIC_NUMBER, 17, \ 60 | struct mpt2_ioctl_iocinfo) 61 | #define MPT2COMMAND _IOWR(MPT2_MAGIC_NUMBER, 20, \ 62 | struct mpt2_ioctl_command) 63 | #ifdef CONFIG_COMPAT 64 | #define MPT2COMMAND32 _IOWR(MPT2_MAGIC_NUMBER, 20, \ 65 | struct mpt2_ioctl_command32) 66 | #endif 67 | #define MPT2EVENTQUERY _IOWR(MPT2_MAGIC_NUMBER, 21, \ 68 | struct mpt2_ioctl_eventquery) 69 | #define MPT2EVENTENABLE _IOWR(MPT2_MAGIC_NUMBER, 22, \ 70 | struct mpt2_ioctl_eventenable) 71 | #define MPT2EVENTREPORT _IOWR(MPT2_MAGIC_NUMBER, 23, \ 72 | struct mpt2_ioctl_eventreport) 73 | #define MPT2HARDRESET _IOWR(MPT2_MAGIC_NUMBER, 24, \ 74 | struct mpt2_ioctl_diag_reset) 75 | #define MPT2BTDHMAPPING _IOWR(MPT2_MAGIC_NUMBER, 31, \ 76 | struct mpt2_ioctl_btdh_mapping) 77 | 78 | /* diag buffer support */ 79 | #define MPT2DIAGREGISTER _IOWR(MPT2_MAGIC_NUMBER, 26, \ 80 | struct mpt2_diag_register) 81 | #define MPT2DIAGRELEASE _IOWR(MPT2_MAGIC_NUMBER, 27, \ 82 | struct mpt2_diag_release) 83 | #define MPT2DIAGUNREGISTER _IOWR(MPT2_MAGIC_NUMBER, 28, \ 84 | struct mpt2_diag_unregister) 85 | #define MPT2DIAGQUERY _IOWR(MPT2_MAGIC_NUMBER, 29, \ 86 | struct mpt2_diag_query) 87 | #define MPT2DIAGREADBUFFER _IOWR(MPT2_MAGIC_NUMBER, 30, \ 88 | struct mpt2_diag_read_buffer) 89 | 90 | /** 91 | * struct mpt2_ioctl_header - main header structure 92 | * @ioc_number - IOC unit number 93 | * @port_number - IOC port number 94 | * @max_data_size - maximum number bytes to transfer on read 95 | */ 96 | struct mpt2_ioctl_header { 97 | uint32_t ioc_number; 98 | uint32_t port_number; 99 | uint32_t max_data_size; 100 | }; 101 | 102 | /** 103 | * struct mpt2_ioctl_diag_reset - diagnostic reset 104 | * @hdr - generic header 105 | */ 106 | struct mpt2_ioctl_diag_reset { 107 | struct mpt2_ioctl_header hdr; 108 | }; 109 | 110 | 111 | /** 112 | * struct mpt2_ioctl_pci_info - pci device info 113 | * @device - pci device id 114 | * @function - pci function id 115 | * @bus - pci bus id 116 | * @segment_id - pci segment id 117 | */ 118 | struct mpt2_ioctl_pci_info { 119 | union { 120 | struct { 121 | uint32_t device:5; 122 | uint32_t function:3; 123 | uint32_t bus:24; 124 | } bits; 125 | uint32_t word; 126 | } u; 127 | uint32_t segment_id; 128 | }; 129 | 130 | 131 | #define MPT2_IOCTL_INTERFACE_SCSI (0x00) 132 | #define MPT2_IOCTL_INTERFACE_FC (0x01) 133 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) 134 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) 135 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) 136 | #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) 137 | #define MPT2_IOCTL_VERSION_LENGTH (32) 138 | 139 | /** 140 | * struct mpt2_ioctl_iocinfo - generic controller info 141 | * @hdr - generic header 142 | * @adapter_type - type of adapter (spi, fc, sas) 143 | * @port_number - port number 144 | * @pci_id - PCI Id 145 | * @hw_rev - hardware revision 146 | * @sub_system_device - PCI subsystem Device ID 147 | * @sub_system_vendor - PCI subsystem Vendor ID 148 | * @rsvd0 - reserved 149 | * @firmware_version - firmware version 150 | * @bios_version - BIOS version 151 | * @driver_version - driver version - 32 ASCII characters 152 | * @rsvd1 - reserved 153 | * @scsi_id - scsi id of adapter 0 154 | * @rsvd2 - reserved 155 | * @pci_information - pci info (2nd revision) 156 | */ 157 | struct mpt2_ioctl_iocinfo { 158 | struct mpt2_ioctl_header hdr; 159 | uint32_t adapter_type; 160 | uint32_t port_number; 161 | uint32_t pci_id; 162 | uint32_t hw_rev; 163 | uint32_t subsystem_device; 164 | uint32_t subsystem_vendor; 165 | uint32_t rsvd0; 166 | uint32_t firmware_version; 167 | uint32_t bios_version; 168 | uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH]; 169 | uint8_t rsvd1; 170 | uint8_t scsi_id; 171 | uint16_t rsvd2; 172 | struct mpt2_ioctl_pci_info pci_information; 173 | }; 174 | 175 | 176 | /* number of event log entries */ 177 | #define MPT2SAS_CTL_EVENT_LOG_SIZE (50) 178 | 179 | /** 180 | * struct mpt2_ioctl_eventquery - query event count and type 181 | * @hdr - generic header 182 | * @event_entries - number of events returned by get_event_report 183 | * @rsvd - reserved 184 | * @event_types - type of events currently being captured 185 | */ 186 | struct mpt2_ioctl_eventquery { 187 | struct mpt2_ioctl_header hdr; 188 | uint16_t event_entries; 189 | uint16_t rsvd; 190 | uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; 191 | }; 192 | 193 | /** 194 | * struct mpt2_ioctl_eventenable - enable/disable event capturing 195 | * @hdr - generic header 196 | * @event_types - toggle off/on type of events to be captured 197 | */ 198 | struct mpt2_ioctl_eventenable { 199 | struct mpt2_ioctl_header hdr; 200 | uint32_t event_types[4]; 201 | }; 202 | 203 | #define MPT2_EVENT_DATA_SIZE (192) 204 | /** 205 | * struct MPT2_IOCTL_EVENTS - 206 | * @event - the event that was reported 207 | * @context - unique value for each event assigned by driver 208 | * @data - event data returned in fw reply message 209 | */ 210 | struct MPT2_IOCTL_EVENTS { 211 | uint32_t event; 212 | uint32_t context; 213 | uint8_t data[MPT2_EVENT_DATA_SIZE]; 214 | }; 215 | 216 | /** 217 | * struct mpt2_ioctl_eventreport - returing event log 218 | * @hdr - generic header 219 | * @event_data - (see struct MPT2_IOCTL_EVENTS) 220 | */ 221 | struct mpt2_ioctl_eventreport { 222 | struct mpt2_ioctl_header hdr; 223 | struct MPT2_IOCTL_EVENTS event_data[1]; 224 | }; 225 | 226 | /** 227 | * struct mpt2_ioctl_command - generic mpt firmware passthru ioclt 228 | * @hdr - generic header 229 | * @timeout - command timeout in seconds. (if zero then use driver default 230 | * value). 231 | * @reply_frame_buf_ptr - reply location 232 | * @data_in_buf_ptr - destination for read 233 | * @data_out_buf_ptr - data source for write 234 | * @sense_data_ptr - sense data location 235 | * @max_reply_bytes - maximum number of reply bytes to be sent to app. 236 | * @data_in_size - number bytes for data transfer in (read) 237 | * @data_out_size - number bytes for data transfer out (write) 238 | * @max_sense_bytes - maximum number of bytes for auto sense buffers 239 | * @data_sge_offset - offset in words from the start of the request message to 240 | * the first SGL 241 | * @mf[1]; 242 | */ 243 | struct mpt2_ioctl_command { 244 | struct mpt2_ioctl_header hdr; 245 | uint32_t timeout; 246 | void __user *reply_frame_buf_ptr; 247 | void __user *data_in_buf_ptr; 248 | void __user *data_out_buf_ptr; 249 | void __user *sense_data_ptr; 250 | uint32_t max_reply_bytes; 251 | uint32_t data_in_size; 252 | uint32_t data_out_size; 253 | uint32_t max_sense_bytes; 254 | uint32_t data_sge_offset; 255 | uint8_t mf[1]; 256 | }; 257 | 258 | #ifdef CONFIG_COMPAT 259 | struct mpt2_ioctl_command32 { 260 | struct mpt2_ioctl_header hdr; 261 | uint32_t timeout; 262 | uint32_t reply_frame_buf_ptr; 263 | uint32_t data_in_buf_ptr; 264 | uint32_t data_out_buf_ptr; 265 | uint32_t sense_data_ptr; 266 | uint32_t max_reply_bytes; 267 | uint32_t data_in_size; 268 | uint32_t data_out_size; 269 | uint32_t max_sense_bytes; 270 | uint32_t data_sge_offset; 271 | uint8_t mf[1]; 272 | }; 273 | #endif 274 | 275 | /** 276 | * struct mpt2_ioctl_btdh_mapping - mapping info 277 | * @hdr - generic header 278 | * @id - target device identification number 279 | * @bus - SCSI bus number that the target device exists on 280 | * @handle - device handle for the target device 281 | * @rsvd - reserved 282 | * 283 | * To obtain a bus/id the application sets 284 | * handle to valid handle, and bus/id to 0xFFFF. 285 | * 286 | * To obtain the device handle the application sets 287 | * bus/id valid value, and the handle to 0xFFFF. 288 | */ 289 | struct mpt2_ioctl_btdh_mapping { 290 | struct mpt2_ioctl_header hdr; 291 | uint32_t id; 292 | uint32_t bus; 293 | uint16_t handle; 294 | uint16_t rsvd; 295 | }; 296 | 297 | 298 | /* status bits for ioc->diag_buffer_status */ 299 | #define MPT2_DIAG_BUFFER_IS_REGISTERED (0x01) 300 | #define MPT2_DIAG_BUFFER_IS_RELEASED (0x02) 301 | #define MPT2_DIAG_BUFFER_IS_DIAG_RESET (0x04) 302 | 303 | /* application flags for mpt2_diag_register, mpt2_diag_query */ 304 | #define MPT2_APP_FLAGS_APP_OWNED (0x0001) 305 | #define MPT2_APP_FLAGS_BUFFER_VALID (0x0002) 306 | #define MPT2_APP_FLAGS_FW_BUFFER_ACCESS (0x0004) 307 | 308 | /* flags for mpt2_diag_read_buffer */ 309 | #define MPT2_FLAGS_REREGISTER (0x0001) 310 | 311 | #define MPT2_PRODUCT_SPECIFIC_DWORDS 23 312 | 313 | /** 314 | * struct mpt2_diag_register - application register with driver 315 | * @hdr - generic header 316 | * @reserved - 317 | * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED 318 | * @application_flags - misc flags 319 | * @diagnostic_flags - specifies flags affecting command processing 320 | * @product_specific - product specific information 321 | * @requested_buffer_size - buffers size in bytes 322 | * @unique_id - tag specified by application that is used to signal ownership 323 | * of the buffer. 324 | * 325 | * This will allow the driver to setup any required buffers that will be 326 | * needed by firmware to communicate with the driver. 327 | */ 328 | struct mpt2_diag_register { 329 | struct mpt2_ioctl_header hdr; 330 | uint8_t reserved; 331 | uint8_t buffer_type; 332 | uint16_t application_flags; 333 | uint32_t diagnostic_flags; 334 | uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS]; 335 | uint32_t requested_buffer_size; 336 | uint32_t unique_id; 337 | }; 338 | 339 | /** 340 | * struct mpt2_diag_unregister - application unregister with driver 341 | * @hdr - generic header 342 | * @unique_id - tag uniquely identifies the buffer to be unregistered 343 | * 344 | * This will allow the driver to cleanup any memory allocated for diag 345 | * messages and to free up any resources. 346 | */ 347 | struct mpt2_diag_unregister { 348 | struct mpt2_ioctl_header hdr; 349 | uint32_t unique_id; 350 | }; 351 | 352 | /** 353 | * struct mpt2_diag_query - query relevant info associated with diag buffers 354 | * @hdr - generic header 355 | * @reserved - 356 | * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED 357 | * @application_flags - misc flags 358 | * @diagnostic_flags - specifies flags affecting command processing 359 | * @product_specific - product specific information 360 | * @total_buffer_size - diag buffer size in bytes 361 | * @driver_added_buffer_size - size of extra space appended to end of buffer 362 | * @unique_id - unique id associated with this buffer. 363 | * 364 | * The application will send only buffer_type and unique_id. Driver will 365 | * inspect unique_id first, if valid, fill in all the info. If unique_id is 366 | * 0x00, the driver will return info specified by Buffer Type. 367 | */ 368 | struct mpt2_diag_query { 369 | struct mpt2_ioctl_header hdr; 370 | uint8_t reserved; 371 | uint8_t buffer_type; 372 | uint16_t application_flags; 373 | uint32_t diagnostic_flags; 374 | uint32_t product_specific[MPT2_PRODUCT_SPECIFIC_DWORDS]; 375 | uint32_t total_buffer_size; 376 | uint32_t driver_added_buffer_size; 377 | uint32_t unique_id; 378 | }; 379 | 380 | /** 381 | * struct mpt2_diag_release - request to send Diag Release Message to firmware 382 | * @hdr - generic header 383 | * @unique_id - tag uniquely identifies the buffer to be released 384 | * 385 | * This allows ownership of the specified buffer to returned to the driver, 386 | * allowing an application to read the buffer without fear that firmware is 387 | * overwritting information in the buffer. 388 | */ 389 | struct mpt2_diag_release { 390 | struct mpt2_ioctl_header hdr; 391 | uint32_t unique_id; 392 | }; 393 | 394 | /** 395 | * struct mpt2_diag_read_buffer - request for copy of the diag buffer 396 | * @hdr - generic header 397 | * @status - 398 | * @reserved - 399 | * @flags - misc flags 400 | * @starting_offset - starting offset within drivers buffer where to start 401 | * reading data at into the specified application buffer 402 | * @bytes_to_read - number of bytes to copy from the drivers buffer into the 403 | * application buffer starting at starting_offset. 404 | * @unique_id - unique id associated with this buffer. 405 | * @diagnostic_data - data payload 406 | */ 407 | struct mpt2_diag_read_buffer { 408 | struct mpt2_ioctl_header hdr; 409 | uint8_t status; 410 | uint8_t reserved; 411 | uint16_t flags; 412 | uint32_t starting_offset; 413 | uint32_t bytes_to_read; 414 | uint32_t unique_id; 415 | uint32_t diagnostic_data[1]; 416 | }; 417 | 418 | #endif /* MPT2SAS_CTL_H_INCLUDED */ 419 | -------------------------------------------------------------------------------- /mpt/mpt3sas_ctl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Management Module Support for MPT (Message Passing Technology) based 3 | * controllers 4 | * 5 | * This code is based on drivers/scsi/mpt3sas/mpt3sas_ctl.h 6 | * Copyright (C) 2012-2014 LSI Corporation 7 | * Copyright (C) 2013-2014 Avago Technologies 8 | * (mailto: MPT-FusionLinux.pdl@avagotech.com) 9 | * 10 | * This program is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU General Public License 12 | * as published by the Free Software Foundation; either version 2 13 | * of the License, or (at your option) any later version. 14 | * 15 | * This program is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | * GNU General Public License for more details. 19 | * 20 | * NO WARRANTY 21 | * THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 22 | * CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 23 | * LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 24 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 25 | * solely responsible for determining the appropriateness of using and 26 | * distributing the Program and assumes all risks associated with its 27 | * exercise of rights under this Agreement, including but not limited to 28 | * the risks and costs of program errors, damage to or loss of data, 29 | * programs or equipment, and unavailability or interruption of operations. 30 | 31 | * DISCLAIMER OF LIABILITY 32 | * NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 33 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 | * DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 35 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 36 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 37 | * USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 38 | * HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 39 | 40 | * You should have received a copy of the GNU General Public License 41 | * along with this program; if not, write to the Free Software 42 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 43 | * USA. 44 | */ 45 | 46 | #ifndef MPT3SAS_CTL_H_INCLUDED 47 | #define MPT3SAS_CTL_H_INCLUDED 48 | 49 | #ifdef __KERNEL__ 50 | #include 51 | #endif 52 | 53 | #ifndef MPT2SAS_MINOR 54 | #define MPT2SAS_MINOR (MPT_MINOR + 1) 55 | #endif 56 | #ifndef MPT3SAS_MINOR 57 | #define MPT3SAS_MINOR (MPT_MINOR + 2) 58 | #endif 59 | #define MPT2SAS_DEV_NAME "mpt2ctl" 60 | #define MPT3SAS_DEV_NAME "mpt3ctl" 61 | #define MPT3_MAGIC_NUMBER 'L' 62 | #define MPT3_IOCTL_DEFAULT_TIMEOUT (10) /* in seconds */ 63 | 64 | /** 65 | * IOCTL opcodes 66 | */ 67 | #define MPT3IOCINFO _IOWR(MPT3_MAGIC_NUMBER, 17, \ 68 | struct mpt3_ioctl_iocinfo) 69 | #define MPT3COMMAND _IOWR(MPT3_MAGIC_NUMBER, 20, \ 70 | struct mpt3_ioctl_command) 71 | #ifdef CONFIG_COMPAT 72 | #define MPT3COMMAND32 _IOWR(MPT3_MAGIC_NUMBER, 20, \ 73 | struct mpt3_ioctl_command32) 74 | #endif 75 | #define MPT3EVENTQUERY _IOWR(MPT3_MAGIC_NUMBER, 21, \ 76 | struct mpt3_ioctl_eventquery) 77 | #define MPT3EVENTENABLE _IOWR(MPT3_MAGIC_NUMBER, 22, \ 78 | struct mpt3_ioctl_eventenable) 79 | #define MPT3EVENTREPORT _IOWR(MPT3_MAGIC_NUMBER, 23, \ 80 | struct mpt3_ioctl_eventreport) 81 | #define MPT3HARDRESET _IOWR(MPT3_MAGIC_NUMBER, 24, \ 82 | struct mpt3_ioctl_diag_reset) 83 | #define MPT3BTDHMAPPING _IOWR(MPT3_MAGIC_NUMBER, 31, \ 84 | struct mpt3_ioctl_btdh_mapping) 85 | 86 | /* diag buffer support */ 87 | #define MPT3DIAGREGISTER _IOWR(MPT3_MAGIC_NUMBER, 26, \ 88 | struct mpt3_diag_register) 89 | #define MPT3DIAGRELEASE _IOWR(MPT3_MAGIC_NUMBER, 27, \ 90 | struct mpt3_diag_release) 91 | #define MPT3DIAGUNREGISTER _IOWR(MPT3_MAGIC_NUMBER, 28, \ 92 | struct mpt3_diag_unregister) 93 | #define MPT3DIAGQUERY _IOWR(MPT3_MAGIC_NUMBER, 29, \ 94 | struct mpt3_diag_query) 95 | #define MPT3DIAGREADBUFFER _IOWR(MPT3_MAGIC_NUMBER, 30, \ 96 | struct mpt3_diag_read_buffer) 97 | 98 | /** 99 | * struct mpt3_ioctl_header - main header structure 100 | * @ioc_number - IOC unit number 101 | * @port_number - IOC port number 102 | * @max_data_size - maximum number bytes to transfer on read 103 | */ 104 | struct mpt3_ioctl_header { 105 | uint32_t ioc_number; 106 | uint32_t port_number; 107 | uint32_t max_data_size; 108 | }; 109 | 110 | /** 111 | * struct mpt3_ioctl_diag_reset - diagnostic reset 112 | * @hdr - generic header 113 | */ 114 | struct mpt3_ioctl_diag_reset { 115 | struct mpt3_ioctl_header hdr; 116 | }; 117 | 118 | 119 | /** 120 | * struct mpt3_ioctl_pci_info - pci device info 121 | * @device - pci device id 122 | * @function - pci function id 123 | * @bus - pci bus id 124 | * @segment_id - pci segment id 125 | */ 126 | struct mpt3_ioctl_pci_info { 127 | union { 128 | struct { 129 | uint32_t device:5; 130 | uint32_t function:3; 131 | uint32_t bus:24; 132 | } bits; 133 | uint32_t word; 134 | } u; 135 | uint32_t segment_id; 136 | }; 137 | 138 | 139 | #define MPT2_IOCTL_INTERFACE_SCSI (0x00) 140 | #define MPT2_IOCTL_INTERFACE_FC (0x01) 141 | #define MPT2_IOCTL_INTERFACE_FC_IP (0x02) 142 | #define MPT2_IOCTL_INTERFACE_SAS (0x03) 143 | #define MPT2_IOCTL_INTERFACE_SAS2 (0x04) 144 | #define MPT2_IOCTL_INTERFACE_SAS2_SSS6200 (0x05) 145 | #define MPT3_IOCTL_INTERFACE_SAS3 (0x06) 146 | #define MPT3_IOCTL_INTERFACE_SAS35 (0x07) 147 | #define MPT2_IOCTL_VERSION_LENGTH (32) 148 | 149 | /** 150 | * struct mpt3_ioctl_iocinfo - generic controller info 151 | * @hdr - generic header 152 | * @adapter_type - type of adapter (spi, fc, sas) 153 | * @port_number - port number 154 | * @pci_id - PCI Id 155 | * @hw_rev - hardware revision 156 | * @sub_system_device - PCI subsystem Device ID 157 | * @sub_system_vendor - PCI subsystem Vendor ID 158 | * @rsvd0 - reserved 159 | * @firmware_version - firmware version 160 | * @bios_version - BIOS version 161 | * @driver_version - driver version - 32 ASCII characters 162 | * @rsvd1 - reserved 163 | * @scsi_id - scsi id of adapter 0 164 | * @rsvd2 - reserved 165 | * @pci_information - pci info (2nd revision) 166 | */ 167 | struct mpt3_ioctl_iocinfo { 168 | struct mpt3_ioctl_header hdr; 169 | uint32_t adapter_type; 170 | uint32_t port_number; 171 | uint32_t pci_id; 172 | uint32_t hw_rev; 173 | uint32_t subsystem_device; 174 | uint32_t subsystem_vendor; 175 | uint32_t rsvd0; 176 | uint32_t firmware_version; 177 | uint32_t bios_version; 178 | uint8_t driver_version[MPT2_IOCTL_VERSION_LENGTH]; 179 | uint8_t rsvd1; 180 | uint8_t scsi_id; 181 | uint16_t rsvd2; 182 | struct mpt3_ioctl_pci_info pci_information; 183 | }; 184 | 185 | 186 | /* number of event log entries */ 187 | #define MPT3SAS_CTL_EVENT_LOG_SIZE (50) 188 | 189 | /** 190 | * struct mpt3_ioctl_eventquery - query event count and type 191 | * @hdr - generic header 192 | * @event_entries - number of events returned by get_event_report 193 | * @rsvd - reserved 194 | * @event_types - type of events currently being captured 195 | */ 196 | struct mpt3_ioctl_eventquery { 197 | struct mpt3_ioctl_header hdr; 198 | uint16_t event_entries; 199 | uint16_t rsvd; 200 | uint32_t event_types[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS]; 201 | }; 202 | 203 | /** 204 | * struct mpt3_ioctl_eventenable - enable/disable event capturing 205 | * @hdr - generic header 206 | * @event_types - toggle off/on type of events to be captured 207 | */ 208 | struct mpt3_ioctl_eventenable { 209 | struct mpt3_ioctl_header hdr; 210 | uint32_t event_types[4]; 211 | }; 212 | 213 | #define MPT3_EVENT_DATA_SIZE (192) 214 | /** 215 | * struct MPT3_IOCTL_EVENTS - 216 | * @event - the event that was reported 217 | * @context - unique value for each event assigned by driver 218 | * @data - event data returned in fw reply message 219 | */ 220 | struct MPT3_IOCTL_EVENTS { 221 | uint32_t event; 222 | uint32_t context; 223 | uint8_t data[MPT3_EVENT_DATA_SIZE]; 224 | }; 225 | 226 | /** 227 | * struct mpt3_ioctl_eventreport - returing event log 228 | * @hdr - generic header 229 | * @event_data - (see struct MPT3_IOCTL_EVENTS) 230 | */ 231 | struct mpt3_ioctl_eventreport { 232 | struct mpt3_ioctl_header hdr; 233 | struct MPT3_IOCTL_EVENTS event_data[1]; 234 | }; 235 | 236 | /** 237 | * struct mpt3_ioctl_command - generic mpt firmware passthru ioctl 238 | * @hdr - generic header 239 | * @timeout - command timeout in seconds. (if zero then use driver default 240 | * value). 241 | * @reply_frame_buf_ptr - reply location 242 | * @data_in_buf_ptr - destination for read 243 | * @data_out_buf_ptr - data source for write 244 | * @sense_data_ptr - sense data location 245 | * @max_reply_bytes - maximum number of reply bytes to be sent to app. 246 | * @data_in_size - number bytes for data transfer in (read) 247 | * @data_out_size - number bytes for data transfer out (write) 248 | * @max_sense_bytes - maximum number of bytes for auto sense buffers 249 | * @data_sge_offset - offset in words from the start of the request message to 250 | * the first SGL 251 | * @mf[1]; 252 | */ 253 | struct mpt3_ioctl_command { 254 | struct mpt3_ioctl_header hdr; 255 | uint32_t timeout; 256 | void __user *reply_frame_buf_ptr; 257 | void __user *data_in_buf_ptr; 258 | void __user *data_out_buf_ptr; 259 | void __user *sense_data_ptr; 260 | uint32_t max_reply_bytes; 261 | uint32_t data_in_size; 262 | uint32_t data_out_size; 263 | uint32_t max_sense_bytes; 264 | uint32_t data_sge_offset; 265 | uint8_t mf[1]; 266 | }; 267 | 268 | #ifdef CONFIG_COMPAT 269 | struct mpt3_ioctl_command32 { 270 | struct mpt3_ioctl_header hdr; 271 | uint32_t timeout; 272 | uint32_t reply_frame_buf_ptr; 273 | uint32_t data_in_buf_ptr; 274 | uint32_t data_out_buf_ptr; 275 | uint32_t sense_data_ptr; 276 | uint32_t max_reply_bytes; 277 | uint32_t data_in_size; 278 | uint32_t data_out_size; 279 | uint32_t max_sense_bytes; 280 | uint32_t data_sge_offset; 281 | uint8_t mf[1]; 282 | }; 283 | #endif 284 | 285 | /** 286 | * struct mpt3_ioctl_btdh_mapping - mapping info 287 | * @hdr - generic header 288 | * @id - target device identification number 289 | * @bus - SCSI bus number that the target device exists on 290 | * @handle - device handle for the target device 291 | * @rsvd - reserved 292 | * 293 | * To obtain a bus/id the application sets 294 | * handle to valid handle, and bus/id to 0xFFFF. 295 | * 296 | * To obtain the device handle the application sets 297 | * bus/id valid value, and the handle to 0xFFFF. 298 | */ 299 | struct mpt3_ioctl_btdh_mapping { 300 | struct mpt3_ioctl_header hdr; 301 | uint32_t id; 302 | uint32_t bus; 303 | uint16_t handle; 304 | uint16_t rsvd; 305 | }; 306 | 307 | 308 | 309 | /* application flags for mpt3_diag_register, mpt3_diag_query */ 310 | #define MPT3_APP_FLAGS_APP_OWNED (0x0001) 311 | #define MPT3_APP_FLAGS_BUFFER_VALID (0x0002) 312 | #define MPT3_APP_FLAGS_FW_BUFFER_ACCESS (0x0004) 313 | 314 | /* flags for mpt3_diag_read_buffer */ 315 | #define MPT3_FLAGS_REREGISTER (0x0001) 316 | 317 | #define MPT3_PRODUCT_SPECIFIC_DWORDS 23 318 | 319 | /** 320 | * struct mpt3_diag_register - application register with driver 321 | * @hdr - generic header 322 | * @reserved - 323 | * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED 324 | * @application_flags - misc flags 325 | * @diagnostic_flags - specifies flags affecting command processing 326 | * @product_specific - product specific information 327 | * @requested_buffer_size - buffers size in bytes 328 | * @unique_id - tag specified by application that is used to signal ownership 329 | * of the buffer. 330 | * 331 | * This will allow the driver to setup any required buffers that will be 332 | * needed by firmware to communicate with the driver. 333 | */ 334 | struct mpt3_diag_register { 335 | struct mpt3_ioctl_header hdr; 336 | uint8_t reserved; 337 | uint8_t buffer_type; 338 | uint16_t application_flags; 339 | uint32_t diagnostic_flags; 340 | uint32_t product_specific[MPT3_PRODUCT_SPECIFIC_DWORDS]; 341 | uint32_t requested_buffer_size; 342 | uint32_t unique_id; 343 | }; 344 | 345 | /** 346 | * struct mpt3_diag_unregister - application unregister with driver 347 | * @hdr - generic header 348 | * @unique_id - tag uniquely identifies the buffer to be unregistered 349 | * 350 | * This will allow the driver to cleanup any memory allocated for diag 351 | * messages and to free up any resources. 352 | */ 353 | struct mpt3_diag_unregister { 354 | struct mpt3_ioctl_header hdr; 355 | uint32_t unique_id; 356 | }; 357 | 358 | /** 359 | * struct mpt3_diag_query - query relevant info associated with diag buffers 360 | * @hdr - generic header 361 | * @reserved - 362 | * @buffer_type - specifies either TRACE, SNAPSHOT, or EXTENDED 363 | * @application_flags - misc flags 364 | * @diagnostic_flags - specifies flags affecting command processing 365 | * @product_specific - product specific information 366 | * @total_buffer_size - diag buffer size in bytes 367 | * @driver_added_buffer_size - size of extra space appended to end of buffer 368 | * @unique_id - unique id associated with this buffer. 369 | * 370 | * The application will send only buffer_type and unique_id. Driver will 371 | * inspect unique_id first, if valid, fill in all the info. If unique_id is 372 | * 0x00, the driver will return info specified by Buffer Type. 373 | */ 374 | struct mpt3_diag_query { 375 | struct mpt3_ioctl_header hdr; 376 | uint8_t reserved; 377 | uint8_t buffer_type; 378 | uint16_t application_flags; 379 | uint32_t diagnostic_flags; 380 | uint32_t product_specific[MPT3_PRODUCT_SPECIFIC_DWORDS]; 381 | uint32_t total_buffer_size; 382 | uint32_t driver_added_buffer_size; 383 | uint32_t unique_id; 384 | }; 385 | 386 | /** 387 | * struct mpt3_diag_release - request to send Diag Release Message to firmware 388 | * @hdr - generic header 389 | * @unique_id - tag uniquely identifies the buffer to be released 390 | * 391 | * This allows ownership of the specified buffer to returned to the driver, 392 | * allowing an application to read the buffer without fear that firmware is 393 | * overwriting information in the buffer. 394 | */ 395 | struct mpt3_diag_release { 396 | struct mpt3_ioctl_header hdr; 397 | uint32_t unique_id; 398 | }; 399 | 400 | /** 401 | * struct mpt3_diag_read_buffer - request for copy of the diag buffer 402 | * @hdr - generic header 403 | * @status - 404 | * @reserved - 405 | * @flags - misc flags 406 | * @starting_offset - starting offset within drivers buffer where to start 407 | * reading data at into the specified application buffer 408 | * @bytes_to_read - number of bytes to copy from the drivers buffer into the 409 | * application buffer starting at starting_offset. 410 | * @unique_id - unique id associated with this buffer. 411 | * @diagnostic_data - data payload 412 | */ 413 | struct mpt3_diag_read_buffer { 414 | struct mpt3_ioctl_header hdr; 415 | uint8_t status; 416 | uint8_t reserved; 417 | uint16_t flags; 418 | uint32_t starting_offset; 419 | uint32_t bytes_to_read; 420 | uint32_t unique_id; 421 | uint32_t diagnostic_data[1]; 422 | }; 423 | 424 | #endif /* MPT3SAS_CTL_H_INCLUDED */ 425 | -------------------------------------------------------------------------------- /mptevents.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include "mpt.h" 18 | 19 | #define DEV_DIR "/dev" 20 | #define MPT2_DIR "/dev/mpt2ctl" 21 | #define MPT3_DIR "/dev/mpt3ctl" 22 | #define SCSIHOST_DIR "/sys/class/scsi_host" 23 | #define MISC_MAJOR_NUM 10 24 | #define MPT2SAS_MINOR_NUM 221 25 | #define MPT3SAS_MINOR_NUM 222 26 | 27 | typedef enum mpt_type { 28 | MPT2SAS, 29 | MPT3SAS 30 | }mpt_type_e; 31 | 32 | typedef struct mpt_ioc { 33 | int ioc_id; 34 | uint32_t ioc_last_context; 35 | mpt_type_e ioc_type; 36 | int ioc_enabled; 37 | }mpt_ioc_t; 38 | 39 | static int opt_debug; 40 | static int opt_stdout; 41 | static int opt_skip_old; 42 | 43 | static void syslog_none(int priority, const char *format, ...) 44 | { 45 | } 46 | 47 | static void syslog_stdout(int priority, const char *format, ...) 48 | { 49 | time_t now; 50 | struct tm *tm; 51 | char timestr[32]; 52 | va_list ap; 53 | 54 | now = time(NULL); 55 | tm = localtime(&now); 56 | strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm); 57 | printf("%s ", timestr); 58 | 59 | va_start(ap, format); 60 | vprintf(format, ap); 61 | va_end(ap); 62 | 63 | putchar('\n'); 64 | fflush(stdout); 65 | } 66 | 67 | static int usage(const char *name) 68 | { 69 | fprintf(stderr, "\nmptevents [options] %s\n", VERSION); 70 | fprintf(stderr, "Usage:\n\t%s \n\tFor example %s /dev/mpt3ctl\n\n", name, name); 71 | fprintf(stderr, "Options:\n"); 72 | fprintf(stderr, " -h --help Display this usage information.\n" 73 | " -d --debug Save raw data to a debug file for later re-parsing with mptevents_offline.\n" 74 | " -o --stdout Output the logs to stdout with a timestamp (else, output to syslog without timestamps).\n" 75 | " -k --skip-old Skip the old events in case of a restart.\n" 76 | "\n" 77 | ); 78 | return 1; 79 | } 80 | 81 | static int find_mpt_host(mpt_ioc_t **ioc_ids, int *ioc_ids_nr) 82 | { 83 | DIR *dir; 84 | struct dirent *dirent; 85 | int fd = -1; 86 | ssize_t ret = -1; 87 | mpt_ioc_t *ids = NULL; 88 | int ids_idx = 0; 89 | int ids_sz = 10; 90 | 91 | ids = malloc(sizeof(*ids) * ids_sz); 92 | if (!ids) 93 | return -1; 94 | 95 | memset(ids, 0x0, sizeof(*ids) * ids_sz); 96 | 97 | dir = opendir(SCSIHOST_DIR); 98 | if (!dir) { 99 | free(ids); 100 | return -1; 101 | } 102 | 103 | while ( (dirent = readdir(dir)) != NULL ) { 104 | char filename[512]; 105 | char procname[8]; 106 | 107 | snprintf(filename, sizeof(filename), "%s/%s/proc_name", SCSIHOST_DIR, dirent->d_name); 108 | 109 | fd = open(filename, O_RDONLY); 110 | if (fd < 0) 111 | continue; 112 | 113 | ret = read(fd, procname, 8); 114 | if (ret < 0) 115 | continue; 116 | 117 | close(fd); 118 | 119 | procname[7] = '\0'; 120 | 121 | if (strncmp("mpt3sas", procname, 7) == 0) { 122 | ids[ids_idx].ioc_type = MPT3SAS; 123 | } else if (strncmp("mpt2sas", procname, 7) == 0) { 124 | ids[ids_idx].ioc_type = MPT2SAS; 125 | } else { 126 | continue; 127 | } 128 | 129 | snprintf(filename, sizeof(filename), "%s/%s/unique_id", SCSIHOST_DIR, dirent->d_name); 130 | 131 | fd = open(filename, O_RDONLY); 132 | if (fd < 0) 133 | continue; 134 | 135 | ret = read(fd, procname, 8); 136 | if (ret < 0) 137 | continue; 138 | 139 | close(fd); 140 | 141 | if (ids_idx == ids_sz) 142 | { 143 | ids_sz *= 2; 144 | ids = realloc(ids, sizeof(*ids) * ids_sz); 145 | if (!ids) 146 | break; 147 | 148 | ids[ids_idx].ioc_id = atoi(procname); 149 | ids[ids_idx].ioc_last_context = 0; 150 | my_syslog(LOG_INFO, "Found MPT ioc %d type %d", 151 | ids[ids_idx].ioc_id, ids[ids_idx].ioc_type); 152 | ids_idx += 1; 153 | } 154 | else 155 | { 156 | ids[ids_idx].ioc_id = atoi(procname); 157 | ids[ids_idx].ioc_last_context = 0; 158 | my_syslog(LOG_INFO, "Found MPT ioc %d type %d", 159 | ids[ids_idx].ioc_id, ids[ids_idx].ioc_type); 160 | ids_idx += 1; 161 | } 162 | } 163 | 164 | closedir(dir); 165 | 166 | *ioc_ids = ids; 167 | *ioc_ids_nr = ids_idx; 168 | 169 | return 0; 170 | } 171 | 172 | static const char *find_mptctl_device(void) 173 | { 174 | DIR *dir; 175 | struct dirent *dirent; 176 | static char matching_filename[256]; 177 | int count = 0; 178 | 179 | matching_filename[0] = 0; 180 | 181 | dir = opendir(DEV_DIR); 182 | if (!dir) 183 | return NULL; 184 | 185 | while ( (dirent = readdir(dir)) != NULL ) { 186 | char filename[512]; 187 | struct stat stbuf; 188 | 189 | snprintf(filename, sizeof(filename), "%s/%s", DEV_DIR, dirent->d_name); 190 | int ret = stat(filename, &stbuf); 191 | 192 | if (ret < 0) 193 | continue; 194 | 195 | if (!S_ISCHR(stbuf.st_mode)) 196 | continue; 197 | 198 | if (major(stbuf.st_rdev) == MISC_MAJOR_NUM && 199 | (minor(stbuf.st_rdev) == MPT2SAS_MINOR_NUM || 200 | minor(stbuf.st_rdev) == MPT3SAS_MINOR_NUM)) { 201 | printf("Found control device: %s\n", filename); 202 | count++; 203 | 204 | strcpy(matching_filename, filename); 205 | } 206 | } 207 | 208 | closedir(dir); 209 | 210 | if (count > 1) { 211 | my_syslog(LOG_CRIT, "More than one control file found, cannot auto-select one!"); 212 | matching_filename[0] = 0; // Empty selection; 213 | } 214 | 215 | // If we have something in the buffer, return it, otherwise we failed 216 | return matching_filename[0] ? matching_filename : NULL; 217 | } 218 | 219 | static const char *parse_opts(int argc, char **argv) 220 | { 221 | int c; 222 | int opt_help = 0; 223 | const char *mptctl_dev = NULL; 224 | 225 | while (1) { 226 | //int this_option_optind = optind ? optind : 1; 227 | int option_index = 0; 228 | static struct option long_options[] = { 229 | {"debug", no_argument, 0, 'd' }, 230 | {"stdout", no_argument, 0, 'o' }, 231 | {"skip-old", no_argument, 0, 'k' }, 232 | {"help", no_argument, 0, 'h' }, 233 | {0, 0, 0, 0 } 234 | }; 235 | 236 | c = getopt_long(argc, argv, "dhok", 237 | long_options, &option_index); 238 | if (c == -1) 239 | break; 240 | 241 | switch (c) { 242 | case 0: 243 | printf("long opt?\n"); 244 | break; 245 | 246 | case 'd': 247 | opt_debug = 1; 248 | break; 249 | 250 | case 'h': 251 | opt_help = 1; 252 | break; 253 | 254 | case 'o': 255 | opt_stdout = 1; 256 | break; 257 | 258 | case 'k': 259 | opt_skip_old = 1; 260 | break; 261 | 262 | default: 263 | return NULL; 264 | } 265 | } 266 | 267 | if (opt_help) { 268 | usage(argv[0]); 269 | return NULL; 270 | } 271 | 272 | if (optind == argc) { 273 | // Try to autodetect a device 274 | mptctl_dev = find_mptctl_device(); 275 | if (!mptctl_dev) { 276 | fprintf(stderr, "Missing device name argument (auto-detection failed)\n"); 277 | usage(argv[0]); 278 | return NULL; 279 | } 280 | } else if (optind != argc-1) { 281 | fprintf(stderr, "Too many devices given, can only monitor one!\n"); 282 | usage(argv[0]); 283 | return NULL; 284 | } else { 285 | mptctl_dev = argv[optind]; 286 | if ((strncmp(MPT2_DIR, mptctl_dev, strlen(MPT2_DIR)) != 0) 287 | && (strncmp(MPT3_DIR, mptctl_dev, strlen(MPT3_DIR)) != 0)) { 288 | fprintf(stderr, "Unsupported device %s.\n", mptctl_dev); 289 | usage(argv[0]); 290 | return NULL; 291 | } 292 | } 293 | 294 | return mptctl_dev; 295 | } 296 | 297 | static int enable_events(int fd, int port, mpt_type_e type) 298 | { 299 | struct mpt2_ioctl_eventenable cmd; 300 | int i; 301 | int ret; 302 | 303 | memset(&cmd, 0, sizeof(cmd)); 304 | cmd.hdr.ioc_number = port; 305 | cmd.hdr.port_number = 0; 306 | 307 | // We want all the events 308 | for (i = 0; i < 4; i++) 309 | cmd.event_types[i] = 0xFFFFFFFF; 310 | 311 | ret = ioctl(fd, (type == MPT2SAS) ? MPT2EVENTENABLE : MPT3EVENTENABLE, &cmd); 312 | if (ret < 0) { 313 | my_syslog(LOG_ERR, "Failed to set the events on mpt device, this might not be a real mpt device: %d (%m)", errno); 314 | } 315 | 316 | my_syslog(LOG_INFO, "Enable the events on ioc %d", port); 317 | 318 | return ret; 319 | } 320 | 321 | /* We have to read all the events and figure out which of them is new and which isn't */ 322 | static int handle_events(int fd, int port, mpt_type_e type, 323 | uint32_t *highest_context, int first_read) 324 | { 325 | struct mpt_events events; 326 | int ret; 327 | 328 | memset(&events, 0, sizeof(events)); 329 | events.hdr.ioc_number = port; 330 | events.hdr.port_number = 0; 331 | events.hdr.max_data_size = sizeof(events); 332 | 333 | ret = ioctl(fd, (type == MPT2SAS) ? MPT2EVENTREPORT : MPT3EVENTREPORT, &events); 334 | if (ret < 0) { 335 | if (errno == EINTR) 336 | return 0; 337 | if (errno == EAGAIN) { 338 | // mpt2sas returns EAGAIN when the controller is busy, avoid a busy loop in that case 339 | sleep(1); 340 | return 0; 341 | } 342 | my_syslog(LOG_ERR, "Error while reading mpt events: %d (%m)", errno); 343 | return -1; 344 | } 345 | 346 | if (opt_debug) { 347 | int debug_fd = open(MPT_EVENTS_LOG, O_WRONLY|O_CREAT|O_APPEND, 0600); 348 | if (debug_fd >= 0) { 349 | uint32_t sz = sizeof(events); 350 | write(debug_fd, &sz, sizeof(sz)); 351 | write(debug_fd, &events, sz); 352 | close(debug_fd); 353 | } 354 | } 355 | 356 | dump_all_events(&events, highest_context, first_read); 357 | return 0; 358 | } 359 | 360 | static void monitor_mpt(int fd) 361 | { 362 | int ret; 363 | int poll_fd; 364 | struct epoll_event event; 365 | mpt_ioc_t *ids = NULL; 366 | int ids_nr = 0; 367 | int idx = 0; 368 | void (*temp_syslog)(int priority, const char *format, ...); 369 | 370 | ret = find_mpt_host(&ids, &ids_nr); 371 | if (ret < 0) 372 | return; 373 | 374 | if (ids_nr == 0) { 375 | free(ids); 376 | my_syslog(LOG_ERR, "Not found any supported MPT ioc"); 377 | return; 378 | } 379 | 380 | for (idx = 0; idx < ids_nr; idx++) { 381 | ret = enable_events(fd, idx, ids[idx].ioc_type); 382 | if (ret < 0) { 383 | ids[idx].ioc_enabled = 0; 384 | continue; 385 | } 386 | 387 | ids[idx].ioc_enabled = 1; 388 | } 389 | 390 | poll_fd = epoll_create(1); 391 | if (poll_fd < 0) { 392 | my_syslog(LOG_ERR, "Error creating epoll to wait for events: %d (%m)", errno); 393 | free(ids); 394 | return; 395 | } 396 | 397 | memset(&event, 0, sizeof(event)); 398 | event.events = EPOLLIN; 399 | event.data.fd = fd; 400 | 401 | ret = epoll_ctl(poll_fd, EPOLL_CTL_ADD, fd, &event); 402 | if (ret < 0) { 403 | my_syslog(LOG_ERR, "Error adding fd to epoll: %d (%m)", errno); 404 | close(poll_fd); 405 | free(ids); 406 | return; 407 | } 408 | 409 | // First run to get the context 410 | if (opt_skip_old) { 411 | temp_syslog = my_syslog; 412 | my_syslog = syslog_none; 413 | } 414 | 415 | for (idx = 0; idx < ids_nr; idx++) { 416 | if (!ids[idx].ioc_enabled) 417 | continue; 418 | 419 | ret = handle_events(fd, idx, ids[idx].ioc_type, 420 | &(ids[idx].ioc_last_context), 1); 421 | if (ret < 0) { 422 | my_syslog(LOG_ERR, "Error while waiting for first mpt events: %d (%m) ioc %d", errno, ids[idx].ioc_id); 423 | } 424 | } 425 | 426 | if (opt_skip_old) { 427 | my_syslog = temp_syslog; 428 | } 429 | 430 | // Now we run the normal loop with the received context 431 | do { 432 | ret = epoll_wait(poll_fd, &event, 1, -1); 433 | if (ret < 0) { 434 | if (errno == EINTR) { 435 | continue; 436 | } else { 437 | my_syslog(LOG_ERR, "Error while waiting for mpt events: %d (%m)", errno); 438 | break; 439 | } 440 | } else if (ret == 0) { 441 | continue; 442 | } 443 | 444 | for (idx = 0; idx < ids_nr; idx++) { 445 | if (!ids[idx].ioc_enabled) 446 | continue; 447 | 448 | ret = handle_events(fd, idx, ids[idx].ioc_type, 449 | &(ids[idx].ioc_last_context), 0); 450 | } 451 | } while (1); 452 | 453 | close(poll_fd); 454 | free(ids); 455 | } 456 | 457 | int main(int argc, char **argv) 458 | { 459 | int attempts; 460 | const char *devname; 461 | 462 | my_syslog = syslog_stdout; 463 | 464 | devname = parse_opts(argc, argv); 465 | if (devname == NULL) 466 | return 1; 467 | 468 | if (opt_stdout) { 469 | my_syslog = syslog_stdout; 470 | } else { 471 | openlog("mptevents", LOG_PERROR, LOG_USER); 472 | my_syslog = syslog; 473 | } 474 | my_syslog(LOG_INFO, "mptevents starting for device %s", devname); 475 | 476 | attempts = 10; 477 | 478 | do { 479 | int fd = open(devname, O_RDWR); 480 | if (fd >= 0) { 481 | monitor_mpt(fd); 482 | close(fd); 483 | } else { 484 | my_syslog(LOG_INFO, "Failed to open mpt device %s: %d (%m)", devname, errno); 485 | attempts--; 486 | } 487 | sleep(30); 488 | } while (attempts > 0); 489 | 490 | my_syslog(LOG_INFO, "mptevents stopping"); 491 | 492 | if (!opt_stdout) 493 | closelog(); 494 | return 0; 495 | } 496 | -------------------------------------------------------------------------------- /mptevents_offline.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "mpt.h" 9 | 10 | static void my_syslog_wrapper(int priority, const char *fmt, ...) 11 | { 12 | va_list ap; 13 | 14 | va_start(ap, fmt); 15 | vprintf(fmt, ap); 16 | va_end(ap); 17 | putchar('\n'); 18 | 19 | (void)priority; // unused 20 | } 21 | 22 | static void usage(const char *name) 23 | { 24 | fprintf(stderr, "\nmptevents_offline %s\n", VERSION); 25 | fprintf(stderr, "Usage:\n\t%s \n\tFor example %s %s\n\n", name, name, MPT_EVENTS_LOG); 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | struct mpt_events events; 31 | int fd; 32 | uint32_t size; 33 | int rc = -1; 34 | int first_read = 1; 35 | uint32_t last_context = 0; 36 | int ret; 37 | 38 | if (argc == 1) { 39 | usage(argv[0]); 40 | return 1; 41 | } 42 | 43 | my_syslog = my_syslog_wrapper; 44 | 45 | fd = open(argv[1], O_RDONLY); 46 | if (fd < 0) { 47 | perror("Failed to open debug file"); 48 | return 1; 49 | } 50 | 51 | while (1) { 52 | ret = read(fd, &size, sizeof(size)); 53 | if (ret == 0) { 54 | printf("EOF\n"); 55 | break; 56 | } 57 | if (ret != sizeof(size)) { 58 | perror("Error reading size from file"); 59 | goto Exit; 60 | } 61 | 62 | if (size != sizeof(struct mpt_events)) { 63 | fprintf(stderr, "Sizes don't match, got %u expected %lu\n", size, sizeof(events)); 64 | goto Exit; 65 | } 66 | 67 | ret = read(fd, &events, sizeof(events)); 68 | if (ret != sizeof(events)) { 69 | perror("Error reading data from dump"); 70 | goto Exit; 71 | } 72 | 73 | dump_all_events(&events, &last_context, first_read); 74 | first_read = 0; 75 | } 76 | 77 | rc = 0; 78 | Exit: 79 | close(fd); 80 | return rc; 81 | } 82 | -------------------------------------------------------------------------------- /mptparser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "mpt.h" 6 | 7 | void (*my_syslog)(int priority, const char *format, ...); 8 | 9 | static inline char nibble_to_hex(char nibble) 10 | { 11 | nibble &= 0xF; 12 | if (nibble < 10) 13 | return '0' + nibble; 14 | else 15 | return 'A' + nibble - 10; 16 | } 17 | 18 | static void buf2hex(char *buf, int buf_len, char *hexbuf, int hexbuf_sz) 19 | { 20 | int i, j; 21 | 22 | for (i = 0, j = 0; i < buf_len && j < hexbuf_sz - 4; i++) { 23 | hexbuf[j++] = nibble_to_hex(buf[i] >> 4); 24 | hexbuf[j++] = nibble_to_hex(buf[i]); 25 | hexbuf[j++] = ' '; 26 | } 27 | hexbuf[j] = 0; 28 | } 29 | 30 | static const char *reason_code_to_text(unsigned rc) 31 | { 32 | switch (rc) { 33 | case MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 34 | return "SMART_DATA"; 35 | case MPI2_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 36 | return "UNSUPPORTED"; 37 | case MPI2_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 38 | return "INTERNAL_DEVICE_RESET"; 39 | case MPI2_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 40 | return "TASK_ABORT_INTERNAL"; 41 | case MPI2_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 42 | return "ABORT_TASK_SET_INTERNAL"; 43 | case MPI2_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 44 | return "CLEAR_TASK_SET_INTERNAL"; 45 | case MPI2_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 46 | return "QUERY_TASK_INTERNAL"; 47 | case MPI2_EVENT_SAS_DEV_STAT_RC_ASYNC_NOTIFICATION: 48 | return "ASYNC_NOTIFICATION"; 49 | case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_INTERNAL_DEV_RESET: 50 | return "COMPLETED_INTERNAL_DEV_RESET"; 51 | case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_TASK_ABORT_INTERNAL: 52 | return "COMPLETED_TASK_ABORT_INTERNAL"; 53 | case MPI2_EVENT_SAS_DEV_STAT_RC_SATA_INIT_FAILURE: 54 | return "SATA_INIT_FAILURE"; 55 | case MPI2_EVENT_SAS_DEV_STAT_RC_EXPANDER_REDUCED_FUNCTIONALITY: 56 | return "EXPANDER_REDUCED_FUNCTIONALITY"; 57 | case MPI2_EVENT_SAS_DEV_STAT_RC_CMP_EXPANDER_REDUCED_FUNCTIONALITY: 58 | return "COMPLETED_EXPANDER_REDUCED_FUNCTIONALITY"; 59 | } 60 | 61 | return "UNKNOWN"; 62 | } 63 | 64 | static void dump_sas_device_status_change(struct MPT2_IOCTL_EVENTS *event, 65 | int ioc) 66 | { 67 | MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *evt = (void*)&event->data; 68 | 69 | my_syslog(LOG_INFO, "SAS Device Status Change: ioc=%d context=%u tag=%04x rc=%u(%s) port=%u asc=%02X ascq=%02X handle=%04x reserved2=%u SASAddress=%"PRIx64, ioc, event->context, evt->TaskTag, evt->ReasonCode, reason_code_to_text(evt->ReasonCode), evt->PhysicalPort, evt->ASC, evt->ASCQ, evt->DevHandle, evt->Reserved2, evt->SASAddress); 70 | } 71 | 72 | static void dump_log_data(struct MPT2_IOCTL_EVENTS *event) 73 | { 74 | MPI2_EVENT_DATA_LOG_ENTRY_ADDED *evt = (void*)&event->data; 75 | char log_data_hex[MPI2_EVENT_DATA_LOG_DATA_LENGTH*3]; // Add place for a space after each hex number and a null 76 | 77 | buf2hex((char*)evt->LogData, MPI2_EVENT_DATA_LOG_DATA_LENGTH, log_data_hex, sizeof(log_data_hex)); 78 | my_syslog(LOG_INFO, "Log Entry Added: context=%u timestamp=%"PRIu64" reserved1=%u seq=%u entry_qualifier=%u vp_id=%u vf_id=%u reserved2=%u log_data='%s'", 79 | event->context, evt->TimeStamp, evt->Reserved1, evt->LogSequence, evt->LogEntryQualifier, evt->VP_ID, evt->VF_ID, evt->Reserved2, log_data_hex); 80 | } 81 | 82 | static void dump_gpio_interrupt(struct MPT2_IOCTL_EVENTS *event) 83 | { 84 | MPI2_EVENT_DATA_GPIO_INTERRUPT *evt = (void*)&event->data; 85 | 86 | my_syslog(LOG_INFO, "GPIO Interrupt: context=%u gpionum=%u reserved1=%u reserved2=%u", event->context, evt->GPIONum, evt->Reserved1, evt->Reserved2); 87 | } 88 | 89 | static void dump_name_only(const char *name, struct MPT2_IOCTL_EVENTS *event) 90 | { 91 | char hexbuf[512]; 92 | 93 | buf2hex((char *)event->data, sizeof(event->data), hexbuf, sizeof(hexbuf)); 94 | my_syslog(LOG_INFO, "%s: event=%u context=%u buf=%s", name, event->event, event->context, hexbuf); 95 | } 96 | 97 | static void dump_temperature_threshold(struct MPT2_IOCTL_EVENTS *event) 98 | { 99 | MPI2_EVENT_DATA_TEMPERATURE *evt = (void*)&event->data; 100 | 101 | my_syslog(LOG_INFO, "Temperature Threshold: context=%u status=%04x sensornum=%u current_temp=%u reversed1=%u reserved2=%u reserved3=%u reserved4=%u", event->context, evt->Status, evt->SensorNum, evt->CurrentTemperature, evt->Reserved1, evt->Reserved2, evt->Reserved3, evt->Reserved4); 102 | } 103 | 104 | static void dump_hard_reset_received(struct MPT2_IOCTL_EVENTS *event) 105 | { 106 | MPI2_EVENT_DATA_HARD_RESET_RECEIVED *evt = (void*)&event->data; 107 | 108 | my_syslog(LOG_INFO, "Hard Reset Received: context=%u port=%u reserved1=%u reserved2=%u", 109 | event->context, 110 | evt->Port, 111 | evt->Reserved1, 112 | evt->Reserved2); 113 | } 114 | 115 | static void dump_task_set_full(struct MPT2_IOCTL_EVENTS *event) 116 | { 117 | MPI2_EVENT_DATA_TASK_SET_FULL *evt = (void*)&event->data; 118 | 119 | my_syslog(LOG_INFO, "Task Set Full: context=%u dev_handle=%hx current_depth=%hu", event->context, evt->DevHandle, evt->CurrentDepth); 120 | } 121 | 122 | static const char *raid_op_to_text(uint8_t raid_op) 123 | { 124 | switch (raid_op) { 125 | case MPI2_EVENT_IR_RAIDOP_RESYNC: 126 | return "RESYNC"; 127 | case MPI2_EVENT_IR_RAIDOP_ONLINE_CAP_EXPANSION: 128 | return "ONLINE_CAPACITY_EXPANSION"; 129 | case MPI2_EVENT_IR_RAIDOP_CONSISTENCY_CHECK: 130 | return "CONSISTENCY_CHECK"; 131 | case MPI2_EVENT_IR_RAIDOP_BACKGROUND_INIT: 132 | return "BACKGROUND_INIT"; 133 | case MPI2_EVENT_IR_RAIDOP_MAKE_DATA_CONSISTENT: 134 | return "MAKE_DATA_CONSISTENT"; 135 | } 136 | 137 | return "UNKNOWN"; 138 | } 139 | 140 | static void dump_ir_operation_status(struct MPT2_IOCTL_EVENTS *event) 141 | { 142 | MPI2_EVENT_DATA_IR_OPERATION_STATUS *evt = (void*)&event->data; 143 | 144 | my_syslog(LOG_INFO, "IR Operation Status: context=%u vol_dev_handle=%hx raid_op=%hhu(%s) percent=%hhu elapsed_sec=%u reserved1=%hu reserved2=%hu", 145 | event->context, 146 | evt->VolDevHandle, 147 | evt->RAIDOperation, raid_op_to_text(evt->RAIDOperation), 148 | evt->PercentComplete, 149 | evt->ElapsedSeconds, 150 | evt->Reserved1, 151 | evt->Reserved2); 152 | } 153 | 154 | static const char *ir_volume_code_to_text(uint8_t rc) 155 | { 156 | switch (rc) { 157 | case MPI2_EVENT_IR_VOLUME_RC_SETTINGS_CHANGED: return "SETTINGS_CHANGED"; 158 | case MPI2_EVENT_IR_VOLUME_RC_STATUS_FLAGS_CHANGED: return "STATUS_FLAGS_CHANGED"; 159 | case MPI2_EVENT_IR_VOLUME_RC_STATE_CHANGED: return "STATE_CHANGED"; 160 | } 161 | 162 | return "UNKNOWN"; 163 | } 164 | 165 | static void dump_ir_volume(struct MPT2_IOCTL_EVENTS *event) 166 | { 167 | MPI2_EVENT_DATA_IR_VOLUME *evt = (void*)&event->data; 168 | 169 | my_syslog(LOG_INFO, "IR Volume: context=%u vol_dev_handle=%hx reason=%hhu(%s) new_value=%u prev_value=%u reserved1=%hhu", 170 | event->context, 171 | evt->VolDevHandle, 172 | evt->ReasonCode, ir_volume_code_to_text(evt->ReasonCode), 173 | evt->NewValue, 174 | evt->PreviousValue, 175 | evt->Reserved1); 176 | } 177 | 178 | static const char *ir_physical_disk_rc_to_text(uint8_t rc) 179 | { 180 | switch (rc) { 181 | case MPI2_EVENT_IR_PHYSDISK_RC_SETTINGS_CHANGED: return "SETTINGS_CHANGED"; 182 | case MPI2_EVENT_IR_PHYSDISK_RC_STATUS_FLAGS_CHANGED: return "STATUS_FLAGS_CHANGED"; 183 | case MPI2_EVENT_IR_PHYSDISK_RC_STATE_CHANGED: return "STATE_CHANGED"; 184 | } 185 | 186 | return "UNKNOWN"; 187 | } 188 | 189 | static void dump_ir_physical_disk(struct MPT2_IOCTL_EVENTS *event) 190 | { 191 | MPI2_EVENT_DATA_IR_PHYSICAL_DISK *evt = (void*)&event->data; 192 | 193 | my_syslog(LOG_INFO, "IR Physical Disk: context=%u reason=%hhu(%s) phys_disk_num=%hhu phys_disk_dev_handle=%hx slot=%hu enclosure_handle=%hu new_value=%u prev_value=%u reserved1=%hu reserved2=%hu", 194 | event->context, 195 | evt->ReasonCode, ir_physical_disk_rc_to_text(evt->ReasonCode), 196 | evt->PhysDiskNum, 197 | evt->PhysDiskDevHandle, 198 | evt->Slot, 199 | evt->EnclosureHandle, 200 | evt->NewValue, 201 | evt->PreviousValue, 202 | evt->Reserved1, 203 | evt->Reserved2); 204 | } 205 | 206 | static const char *ir_config_element_flag_to_text(uint16_t flags) 207 | { 208 | switch (flags & MPI2_EVENT_IR_CHANGE_EFLAGS_ELEMENT_TYPE_MASK) { 209 | case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLUME_ELEMENT: return "VOLUME_ELEMENT"; 210 | case MPI2_EVENT_IR_CHANGE_EFLAGS_VOLPHYSDISK_ELEMENT: return "VOLPHYSDISK_ELEMENT"; 211 | case MPI2_EVENT_IR_CHANGE_EFLAGS_HOTSPARE_ELEMENT: return "HOTSPARE_ELEMENT"; 212 | } 213 | 214 | return "UNKNOWN"; 215 | } 216 | 217 | static const char *ir_config_element_reason_to_text(uint8_t rc) 218 | { 219 | switch (rc) { 220 | case MPI2_EVENT_IR_CHANGE_RC_ADDED: return "ADDED"; 221 | case MPI2_EVENT_IR_CHANGE_RC_REMOVED: return "REMOVED"; 222 | case MPI2_EVENT_IR_CHANGE_RC_NO_CHANGE: return "NO_CHANGE"; 223 | case MPI2_EVENT_IR_CHANGE_RC_HIDE: return "HIDE"; 224 | case MPI2_EVENT_IR_CHANGE_RC_UNHIDE: return "UNHIDE"; 225 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_CREATED: return "VOLUME_CREATED"; 226 | case MPI2_EVENT_IR_CHANGE_RC_VOLUME_DELETED: return "VOLUME_DELETED"; 227 | case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED: return "PD_CREATED"; 228 | case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED: return "PD_DELETED"; 229 | } 230 | 231 | return "UNKNOWN"; 232 | } 233 | 234 | static void dump_ir_config_change_list(struct MPT2_IOCTL_EVENTS *event) 235 | { 236 | MPI2_EVENT_DATA_IR_CONFIG_CHANGE_LIST *evt = (void*)&event->data; 237 | 238 | my_syslog(LOG_INFO, "IR Config Change List: context=%u num_elements=%hhu config_num=%hhu flags=%x reserved1=%hhu reserved2=%hhu", 239 | event->context, 240 | evt->NumElements, 241 | evt->ConfigNum, 242 | evt->Flags, 243 | evt->Reserved1, 244 | evt->Reserved2); 245 | 246 | int i; 247 | for (i = 0; i < evt->NumElements; i++) { 248 | MPI2_EVENT_IR_CONFIG_ELEMENT *elem = &evt->ConfigElement[i]; 249 | my_syslog(LOG_INFO, "IR Config Change List Element (%d/%d): flags=%hx(%s) vol_dev_handle=%hx reason=%hhu(%s) phys_disk_num=%hhu phys_disk_dev_handle=%hx", 250 | i+1, evt->NumElements, 251 | elem->ElementFlags, ir_config_element_flag_to_text(elem->ElementFlags), 252 | elem->VolDevHandle, 253 | elem->ReasonCode, ir_config_element_reason_to_text(elem->ReasonCode), 254 | elem->PhysDiskNum, 255 | elem->PhysDiskDevHandle); 256 | } 257 | } 258 | 259 | static const char *sas_discovery_flags_to_text(uint8_t flags) 260 | { 261 | static char text[128]; 262 | int i = 0; 263 | 264 | text[0] = 0; // Re-initialize static buffer 265 | if (flags & MPI2_EVENT_SAS_DISC_IN_PROGRESS) 266 | i += sprintf(text, "%s", "IN_PROGRESS"); 267 | if (flags & MPI2_EVENT_SAS_DISC_DEVICE_CHANGE) { 268 | if (i > 0) 269 | text[i++] = ','; 270 | sprintf(text + i, "%s", "DEVICE_CHANGE"); 271 | } 272 | return text; 273 | } 274 | 275 | static const char *sas_discovery_reason_to_text(uint8_t reason) 276 | { 277 | if (reason == MPI2_EVENT_SAS_DISC_RC_STARTED) 278 | return "STARTED"; 279 | else if (reason == MPI2_EVENT_SAS_DISC_RC_COMPLETED) 280 | return "COMPLETED"; 281 | else 282 | return "UNKNOWN"; 283 | } 284 | 285 | static const char *sas_discovery_status_to_text(uint32_t status) 286 | { 287 | static char text[256]; 288 | int i = 0; 289 | 290 | text[0] = 0; // Re-initialize static buffer 291 | #define OUTPUT_FLAG(val, name) \ 292 | do { \ 293 | if (status & val) { \ 294 | if (i > 0) \ 295 | text[i++] = ','; \ 296 | i += sprintf(text+i, "%s", name); \ 297 | } \ 298 | } while (0) 299 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MAX_ENCLOSURES_EXCEED, "MAX_ENCLOSURES_EXCEED"); 300 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MAX_EXPANDERS_EXCEED, "MAX_EXPANDERS_EXCEED"); 301 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MAX_DEVICES_EXCEED, "MAX_DEVICES_EXCEED"); 302 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MAX_TOPO_PHYS_EXCEED, "MAX_TOPO_PHYS_EXCEED"); 303 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_DOWNSTREAM_INITIATOR, "DOWNSTREAM_INITIATOR"); 304 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MULTI_SUBTRACTIVE_SUBTRACTIVE, "MULTI_SUBTRACTIVE_SUBTRACTIVE"); 305 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_EXP_MULTI_SUBTRACTIVE, "EXP_MULTI_SUBTRACTIVE"); 306 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MULTI_PORT_DOMAIN, "MULTI_PORT_DOMAIN"); 307 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_TABLE_TO_SUBTRACTIVE_LINK, "TABLE_TO_SUBTRACTIVE_LINK"); 308 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_UNSUPPORTED_DEVICE, "UNSUPPORTED_DEVICE"); 309 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_TABLE_LINK, "TABLE_LINK"); 310 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_SUBTRACTIVE_LINK, "SUBTRACTIVE_LINK"); 311 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_SMP_CRC_ERROR, "SMP_CRC_ERROR"); 312 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_SMP_FUNCTION_FAILED, "SMP_FUNCTION_FAILED"); 313 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_INDEX_NOT_EXIST, "INDEX_NOT_EXIST"); 314 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_OUT_ROUTE_ENTRIES, "OUT_ROUTE_ENTRIES"); 315 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_SMP_TIMEOUT, "SMP_TIMEOUT"); 316 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_MULTIPLE_PORTS, "MULTIPLE_PORTS"); 317 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_UNADDRESSABLE_DEVICE, "UNADDRESSABLE_DEVICE"); 318 | OUTPUT_FLAG(MPI2_EVENT_SAS_DISC_DS_LOOP_DETECTED, "LOOP_DETECTED"); 319 | #undef OUTPUT_FLAG 320 | 321 | return text; 322 | } 323 | 324 | 325 | static void dump_sas_discovery(struct MPT2_IOCTL_EVENTS *event) 326 | { 327 | MPI2_EVENT_DATA_SAS_DISCOVERY *evt = (void*)&event->data; 328 | 329 | my_syslog(LOG_INFO, "SAS Discovery: context=%u flags=%02hhx(%s) reason=%hhx(%s) physical_port=%hhx discovery_status=%x(%s) reserved1=%hhx", 330 | event->context, 331 | evt->Flags, sas_discovery_flags_to_text(evt->Flags), 332 | evt->ReasonCode, sas_discovery_reason_to_text(evt->ReasonCode), 333 | evt->PhysicalPort, 334 | evt->DiscoveryStatus, sas_discovery_status_to_text(evt->DiscoveryStatus), 335 | evt->Reserved1); 336 | } 337 | 338 | static const char *sas_broadcast_primitive_to_text(uint8_t primitive) 339 | { 340 | switch (primitive) { 341 | case MPI2_EVENT_PRIMITIVE_CHANGE: return "CHANGE"; 342 | case MPI2_EVENT_PRIMITIVE_SES: return "SES"; 343 | case MPI2_EVENT_PRIMITIVE_EXPANDER: return "EXPANDER"; 344 | case MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT: return "ASYNCHRONOUS_EVENT"; 345 | case MPI2_EVENT_PRIMITIVE_RESERVED3: return "RESERVED3"; 346 | case MPI2_EVENT_PRIMITIVE_RESERVED4: return "RESERVED4"; 347 | case MPI2_EVENT_PRIMITIVE_CHANGE0_RESERVED: return "CHANGE0_RESERVED"; 348 | case MPI2_EVENT_PRIMITIVE_CHANGE1_RESERVED: return "CHANGE1_RESERVED"; 349 | } 350 | 351 | return "UNKNOWN"; 352 | } 353 | 354 | static void dump_sas_broadcast_primitive(struct MPT2_IOCTL_EVENTS *event) 355 | { 356 | MPI2_EVENT_DATA_SAS_BROADCAST_PRIMITIVE *evt = (void*)&event->data; 357 | 358 | my_syslog(LOG_INFO, "SAS Broadcast Primitive: context=%u phy_num=%hhu port=%hhu port_width=%hhu primitive=%hhu(%s)", 359 | event->context, 360 | evt->PhyNum, 361 | evt->Port, 362 | evt->PortWidth, 363 | evt->Primitive, sas_broadcast_primitive_to_text(evt->Primitive)); 364 | } 365 | 366 | static const char *sas_notify_primitive_to_text(uint8_t primitive) 367 | { 368 | switch (primitive) { 369 | case MPI2_EVENT_NOTIFY_ENABLE_SPINUP: return "ENABLE_SPINUP"; 370 | case MPI2_EVENT_NOTIFY_POWER_LOSS_EXPECTED: return "POWER_LOSS_EXPECTED"; 371 | case MPI2_EVENT_NOTIFY_RESERVED1: return "RESERVED1"; 372 | case MPI2_EVENT_NOTIFY_RESERVED2: return "RESERVED2"; 373 | } 374 | 375 | return "UNKNOWN"; 376 | } 377 | 378 | static void dump_sas_notify_primitive(struct MPT2_IOCTL_EVENTS *event) 379 | { 380 | MPI2_EVENT_DATA_SAS_NOTIFY_PRIMITIVE *evt = (void*)&event->data; 381 | 382 | my_syslog(LOG_INFO, "SAS Notify Primitive: context=%u phy_num=%hhu port=%hhu primitive=%hhu(%s) reserved1=%hhx", 383 | event->context, 384 | evt->PhyNum, 385 | evt->Port, 386 | evt->Primitive, sas_notify_primitive_to_text(evt->Primitive), 387 | evt->Reserved1); 388 | } 389 | 390 | static const char *sas_init_dev_status_reason_to_text(uint8_t reason) 391 | { 392 | switch (reason) { 393 | case MPI2_EVENT_SAS_INIT_RC_ADDED: return "ADDED"; 394 | case MPI2_EVENT_SAS_INIT_RC_NOT_RESPONDING: return "NOT_RESPONDING"; 395 | } 396 | 397 | return "UNKNOWN"; 398 | } 399 | 400 | static void dump_sas_init_dev_status_change(struct MPT2_IOCTL_EVENTS *event) 401 | { 402 | MPI2_EVENT_DATA_SAS_INIT_DEV_STATUS_CHANGE *evt = (void*)&event->data; 403 | 404 | my_syslog(LOG_INFO, "SAS Init Dev Status Change: context=%u reason=%hhd(%s) phys_port=%hhu dev_handle=%hu sas_address=%"PRIx64, 405 | event->context, 406 | evt->ReasonCode, sas_init_dev_status_reason_to_text(evt->ReasonCode), 407 | evt->PhysicalPort, 408 | evt->DevHandle, 409 | evt->SASAddress); 410 | } 411 | 412 | static void dump_sas_init_table_overflow(struct MPT2_IOCTL_EVENTS *event) 413 | { 414 | MPI2_EVENT_DATA_SAS_INIT_TABLE_OVERFLOW *evt = (void*)&event->data; 415 | 416 | my_syslog(LOG_INFO, "SAS Init Table Overflow: context=%u max_init=%hu current_init=%hu sas_address=%"PRIx64, 417 | event->context, 418 | evt->MaxInit, 419 | evt->CurrentInit, 420 | evt->SASAddress); 421 | } 422 | 423 | static const char *sas_topology_change_list_status_to_text(uint8_t status) 424 | { 425 | switch (status) { 426 | case MPI2_EVENT_SAS_TOPO_ES_NO_EXPANDER: return "NO_EXPANDER"; 427 | case MPI2_EVENT_SAS_TOPO_ES_ADDED: return "ADDED"; 428 | case MPI2_EVENT_SAS_TOPO_ES_NOT_RESPONDING: return "NOT_RESPONDING"; 429 | case MPI2_EVENT_SAS_TOPO_ES_RESPONDING: return "RESPONDING"; 430 | case MPI2_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: return "DELAY_NOT_RESPONDING"; 431 | } 432 | 433 | return "UNKNOWN"; 434 | } 435 | 436 | static const char *sas_topo_link_rate_to_text(uint8_t link_rate) 437 | { 438 | switch (link_rate) { 439 | case MPI2_EVENT_SAS_TOPO_LR_UNKNOWN_LINK_RATE: return "UNKNOWN_LINK_RATE"; 440 | case MPI2_EVENT_SAS_TOPO_LR_PHY_DISABLED: return "PHY_DISABLED"; 441 | case MPI2_EVENT_SAS_TOPO_LR_NEGOTIATION_FAILED: return "NEGOTIATION_FAILED"; 442 | case MPI2_EVENT_SAS_TOPO_LR_SATA_OOB_COMPLETE: return "SATA_OOB_COMPLETE"; 443 | case MPI2_EVENT_SAS_TOPO_LR_PORT_SELECTOR: return "PORT_SELECTOR"; 444 | case MPI2_EVENT_SAS_TOPO_LR_SMP_RESET_IN_PROGRESS: return "SMP_RESET_IN_PROGRESS"; 445 | case MPI2_EVENT_SAS_TOPO_LR_UNSUPPORTED_PHY: return "UNSUPPORTED_PHY"; 446 | case MPI2_EVENT_SAS_TOPO_LR_RATE_1_5: return "RATE_1_5"; 447 | case MPI2_EVENT_SAS_TOPO_LR_RATE_3_0: return "RATE_3_0"; 448 | case MPI2_EVENT_SAS_TOPO_LR_RATE_6_0: return "RATE_6_0"; 449 | case MPI25_EVENT_SAS_TOPO_LR_RATE_12_0: return "RATE_12_0"; 450 | } 451 | 452 | return "UNKNOWN"; 453 | } 454 | 455 | static const char *sas_topo_phy_status_to_text(uint8_t status) 456 | { 457 | static char text[256]; 458 | int i = 0; 459 | 460 | text[0] = 0; // Re-initialize static buffer 461 | #define OUTPUT_FLAG(val, name) \ 462 | do { \ 463 | if (status & val) { \ 464 | if (i > 0) \ 465 | text[i++] = ','; \ 466 | i += sprintf(text+i, "%s", name); \ 467 | } \ 468 | } while (0) 469 | OUTPUT_FLAG(MPI2_EVENT_SAS_TOPO_PHYSTATUS_VACANT, "PHYSTATUS_VACANT"); 470 | OUTPUT_FLAG(0x40, "UNKNOWN_40"); 471 | OUTPUT_FLAG(0x20, "UNKNOWN_20"); 472 | OUTPUT_FLAG(MPI2_EVENT_SAS_TOPO_PS_MULTIPLEX_CHANGE, "PS_MULTIPLEX_CHANGE"); 473 | #undef OUTPUT_FLAG 474 | 475 | const char *rc = "UNKNOWN"; 476 | switch (status & MPI2_EVENT_SAS_TOPO_RC_MASK) { 477 | case MPI2_EVENT_SAS_TOPO_RC_TARG_ADDED: rc = "TARG_ADDED"; break; 478 | case MPI2_EVENT_SAS_TOPO_RC_TARG_NOT_RESPONDING: rc = "TARG_NOT_RESPONDING"; break; 479 | case MPI2_EVENT_SAS_TOPO_RC_PHY_CHANGED: rc = "PHY_CHANGED"; break; 480 | case MPI2_EVENT_SAS_TOPO_RC_NO_CHANGE: rc = "NO_CHANGE"; break; 481 | case MPI2_EVENT_SAS_TOPO_RC_DELAY_NOT_RESPONDING: rc = "DELAY_NOT_RESPONDING"; break; 482 | } 483 | 484 | if (i > 0) 485 | text[i++] = ','; 486 | sprintf(text+i, "%s", rc); 487 | 488 | return text; 489 | } 490 | 491 | static void dump_sas_topology_change_list(struct MPT2_IOCTL_EVENTS *event) 492 | { 493 | MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *evt = (void*)&event->data; 494 | 495 | my_syslog(LOG_INFO, "SAS Topology Change List: context=%u enclosure_handle=%hx expander_dev_handle=%hx num_phys=%hhu num_entries=%hhu start_phy_num=%hhu exp_status=%hhu(%s) physical_port=%hhu reserved1=%hhu reserved2=%hu", 496 | event->context, 497 | evt->EnclosureHandle, 498 | evt->ExpanderDevHandle, 499 | evt->NumPhys, 500 | evt->NumEntries, 501 | evt->StartPhyNum, 502 | evt->ExpStatus, sas_topology_change_list_status_to_text(evt->ExpStatus), 503 | evt->PhysicalPort, 504 | evt->Reserved1, 505 | evt->Reserved2); 506 | 507 | int i; 508 | for (i = 0; i < evt->NumEntries; i++) { 509 | MPI2_EVENT_SAS_TOPO_PHY_ENTRY *entry = &evt->PHY[i]; 510 | my_syslog(LOG_INFO, "SAS Topology Change List Entry (%d/%d): attached_dev_handle=%hx link_rate=%hhx(prev=%s,next=%s) phy_status=%hhu(%s)", 511 | i+1, evt->NumEntries, 512 | entry->AttachedDevHandle, 513 | entry->LinkRate, 514 | sas_topo_link_rate_to_text((entry->LinkRate & MPI2_EVENT_SAS_TOPO_LR_PREV_MASK) >> MPI2_EVENT_SAS_TOPO_LR_PREV_SHIFT), 515 | sas_topo_link_rate_to_text((entry->LinkRate & MPI2_EVENT_SAS_TOPO_LR_CURRENT_MASK) >> MPI2_EVENT_SAS_TOPO_LR_CURRENT_SHIFT), 516 | entry->PhyStatus, sas_topo_phy_status_to_text(entry->PhyStatus)); 517 | } 518 | } 519 | 520 | static const char *sas_enclosure_dev_status_change_reason_to_text(uint8_t reason) 521 | { 522 | switch (reason) { 523 | case MPI2_EVENT_SAS_ENCL_RC_ADDED: return "ADDED"; 524 | case MPI2_EVENT_SAS_ENCL_RC_NOT_RESPONDING: return "NOT_RESPONDING"; 525 | } 526 | 527 | return "UNKNOWN"; 528 | } 529 | 530 | static void dump_sas_enclosure_device_status_change(struct MPT2_IOCTL_EVENTS *event) 531 | { 532 | MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *evt = (void*)&event->data; 533 | 534 | my_syslog(LOG_INFO, "SAS Enclosure Device Status Change: context=%u enclosure_handle=%hx reason=%hhu(%s) enclosure_logical_id=%"PRIx64" num_slots=%hu start_slot=%hu phy_bits=%x", 535 | event->context, 536 | evt->EnclosureHandle, 537 | evt->ReasonCode, sas_enclosure_dev_status_change_reason_to_text(evt->ReasonCode), 538 | evt->EnclosureLogicalID, 539 | evt->NumSlots, 540 | evt->StartSlot, 541 | evt->PhyBits); 542 | } 543 | 544 | static const char *sas_quiesce_reason_to_text(uint8_t reason) 545 | { 546 | switch (reason) { 547 | case MPI2_EVENT_SAS_QUIESCE_RC_STARTED: return "STARTED"; 548 | case MPI2_EVENT_SAS_QUIESCE_RC_COMPLETED: return "COMPLETED"; 549 | } 550 | 551 | return "UNKNOWN"; 552 | } 553 | 554 | static void dump_sas_quiesce(struct MPT2_IOCTL_EVENTS *event) 555 | { 556 | MPI2_EVENT_DATA_SAS_QUIESCE *evt = (void*)&event->data; 557 | 558 | my_syslog(LOG_INFO, "SAS Quiesce: context=%u reason=%hhu(%s) reserved1=%hhu reserved2=%hu reserved3=%u", 559 | event->context, 560 | evt->ReasonCode, sas_quiesce_reason_to_text(evt->ReasonCode), 561 | evt->Reserved1, 562 | evt->Reserved2, 563 | evt->Reserved3); 564 | } 565 | 566 | static const char *phy_event_code_to_text(uint8_t code) 567 | { 568 | switch (code) { 569 | case MPI2_SASPHY3_EVENT_CODE_NO_EVENT: return "NO_EVENT"; 570 | case MPI2_SASPHY3_EVENT_CODE_INVALID_DWORD: return "INVALID_DWORD"; 571 | case MPI2_SASPHY3_EVENT_CODE_RUNNING_DISPARITY_ERROR: return "RUNNING_DISPARITY_ERROR"; 572 | case MPI2_SASPHY3_EVENT_CODE_LOSS_DWORD_SYNC: return "LOSS_DWORD_SYNC"; 573 | case MPI2_SASPHY3_EVENT_CODE_PHY_RESET_PROBLEM: return "PHY_RESET_PROBLEM"; 574 | case MPI2_SASPHY3_EVENT_CODE_ELASTICITY_BUF_OVERFLOW: return "ELASTICITY_BUF_OVERFLOW"; 575 | case MPI2_SASPHY3_EVENT_CODE_RX_ERROR: return "RX_ERROR"; 576 | case MPI2_SASPHY3_EVENT_CODE_RX_ADDR_FRAME_ERROR: return "RX_ADDR_FRAME_ERROR"; 577 | case MPI2_SASPHY3_EVENT_CODE_TX_AC_OPEN_REJECT: return "TX_AC_OPEN_REJECT"; 578 | case MPI2_SASPHY3_EVENT_CODE_RX_AC_OPEN_REJECT: return "RX_AC_OPEN_REJECT"; 579 | case MPI2_SASPHY3_EVENT_CODE_TX_RC_OPEN_REJECT: return "TX_RC_OPEN_REJECT"; 580 | case MPI2_SASPHY3_EVENT_CODE_RX_RC_OPEN_REJECT: return "RX_RC_OPEN_REJECT"; 581 | case MPI2_SASPHY3_EVENT_CODE_RX_AIP_PARTIAL_WAITING_ON: return "RX_AIP_PARTIAL_WAITING_ON"; 582 | case MPI2_SASPHY3_EVENT_CODE_RX_AIP_CONNECT_WAITING_ON: return "RX_AIP_CONNECT_WAITING_ON"; 583 | case MPI2_SASPHY3_EVENT_CODE_TX_BREAK: return "TX_BREAK"; 584 | case MPI2_SASPHY3_EVENT_CODE_RX_BREAK: return "RX_BREAK"; 585 | case MPI2_SASPHY3_EVENT_CODE_BREAK_TIMEOUT: return "BREAK_TIMEOUT"; 586 | case MPI2_SASPHY3_EVENT_CODE_CONNECTION: return "CONNECTION"; 587 | case MPI2_SASPHY3_EVENT_CODE_PEAKTX_PATHWAY_BLOCKED: return "PEAKTX_PATHWAY_BLOCKED"; 588 | case MPI2_SASPHY3_EVENT_CODE_PEAKTX_ARB_WAIT_TIME: return "PEAKTX_ARB_WAIT_TIME"; 589 | case MPI2_SASPHY3_EVENT_CODE_PEAK_ARB_WAIT_TIME: return "PEAK_ARB_WAIT_TIME"; 590 | case MPI2_SASPHY3_EVENT_CODE_PEAK_CONNECT_TIME: return "PEAK_CONNECT_TIME"; 591 | case MPI2_SASPHY3_EVENT_CODE_TX_SSP_FRAMES: return "TX_SSP_FRAMES"; 592 | case MPI2_SASPHY3_EVENT_CODE_RX_SSP_FRAMES: return "RX_SSP_FRAMES"; 593 | case MPI2_SASPHY3_EVENT_CODE_TX_SSP_ERROR_FRAMES: return "TX_SSP_ERROR_FRAMES"; 594 | case MPI2_SASPHY3_EVENT_CODE_RX_SSP_ERROR_FRAMES: return "RX_SSP_ERROR_FRAMES"; 595 | case MPI2_SASPHY3_EVENT_CODE_TX_CREDIT_BLOCKED: return "TX_CREDIT_BLOCKED"; 596 | case MPI2_SASPHY3_EVENT_CODE_RX_CREDIT_BLOCKED: return "RX_CREDIT_BLOCKED"; 597 | case MPI2_SASPHY3_EVENT_CODE_TX_SATA_FRAMES: return "TX_SATA_FRAMES"; 598 | case MPI2_SASPHY3_EVENT_CODE_RX_SATA_FRAMES: return "RX_SATA_FRAMES"; 599 | case MPI2_SASPHY3_EVENT_CODE_SATA_OVERFLOW: return "SATA_OVERFLOW"; 600 | case MPI2_SASPHY3_EVENT_CODE_TX_SMP_FRAMES: return "TX_SMP_FRAMES"; 601 | case MPI2_SASPHY3_EVENT_CODE_RX_SMP_FRAMES: return "RX_SMP_FRAMES"; 602 | case MPI2_SASPHY3_EVENT_CODE_RX_SMP_ERROR_FRAMES: return "RX_SMP_ERROR_FRAMES"; 603 | case MPI2_SASPHY3_EVENT_CODE_HOTPLUG_TIMEOUT: return "HOTPLUG_TIMEOUT"; 604 | case MPI2_SASPHY3_EVENT_CODE_MISALIGNED_MUX_PRIMITIVE: return "MISALIGNED_MUX_PRIMITIVE"; 605 | case MPI2_SASPHY3_EVENT_CODE_RX_AIP: return "RX_AIP"; 606 | } 607 | 608 | return "UNKNOWN"; 609 | } 610 | 611 | static const char *counter_type_to_text(uint8_t type) 612 | { 613 | switch (type) { 614 | case MPI2_SASPHY3_COUNTER_TYPE_WRAPPING: return "WRAPPING"; 615 | case MPI2_SASPHY3_COUNTER_TYPE_SATURATING: return "SATURATING"; 616 | case MPI2_SASPHY3_COUNTER_TYPE_PEAK_VALUE: return "PEAK_VALUE"; 617 | } 618 | 619 | return "UNKNOWN"; 620 | } 621 | 622 | static const char *time_units_to_text(uint8_t unit) 623 | { 624 | switch (unit) { 625 | case MPI2_SASPHY3_TIME_UNITS_10_MICROSECONDS: return "10_MICROSECONDS"; 626 | case MPI2_SASPHY3_TIME_UNITS_100_MICROSECONDS: return "100_MICROSECONDS"; 627 | case MPI2_SASPHY3_TIME_UNITS_1_MILLISECOND: return "1_MILLISECOND"; 628 | case MPI2_SASPHY3_TIME_UNITS_10_MILLISECONDS: return "10_MILLISECONDS"; 629 | } 630 | 631 | return "UNKNOWN"; 632 | } 633 | 634 | static const char *threshold_flags_to_text(uint8_t flags) 635 | { 636 | switch (flags) { 637 | case MPI2_SASPHY3_TFLAGS_PHY_RESET: return "PHY_RESET"; 638 | case MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY: return "EVENT_NOTIFY"; 639 | case MPI2_SASPHY3_TFLAGS_EVENT_NOTIFY|MPI2_SASPHY3_TFLAGS_PHY_RESET: return "PHY_RESET,EVENT_NOTIFY"; 640 | } 641 | 642 | return "UNKNOWN"; 643 | } 644 | 645 | static void dump_sas_phy_counter(struct MPT2_IOCTL_EVENTS *event) 646 | { 647 | MPI2_EVENT_DATA_SAS_PHY_COUNTER *evt = (void*)&event->data; 648 | 649 | my_syslog(LOG_INFO, "SAS Phy Counter: context=%u timestamp=%"PRIu64" phy_event_code=%hhu(%s) phy_num=%hhu phy_event_info=%x counter_type=%hhu(%s) threshold_window=%hhu time_units=%hhu(%s) event_threshold=%u threshold_flags=%hx(%s) reserved1=%u reserved2=%hu reserved3=%hhu reserved4=%hu", 650 | event->context, 651 | evt->TimeStamp, 652 | evt->PhyEventCode, phy_event_code_to_text(evt->PhyEventCode), 653 | evt->PhyNum, 654 | evt->PhyEventInfo, 655 | evt->CounterType, counter_type_to_text(evt->CounterType), 656 | evt->ThresholdWindow, 657 | evt->TimeUnits, time_units_to_text(evt->TimeUnits), 658 | evt->EventThreshold, 659 | evt->ThresholdFlags, threshold_flags_to_text(evt->ThresholdFlags), 660 | evt->Reserved1, 661 | evt->Reserved2, 662 | evt->Reserved3, 663 | evt->Reserved4); 664 | } 665 | 666 | static const char *power_mode_init_to_text(uint8_t val) 667 | { 668 | val &= MPI2_EVENT_PM_INIT_MASK; 669 | 670 | switch (val) { 671 | case MPI2_EVENT_PM_INIT_UNAVAILABLE: return "INIT_UNAVAILABLE"; 672 | case MPI2_EVENT_PM_INIT_HOST: return "INIT_HOST"; 673 | case MPI2_EVENT_PM_INIT_IO_UNIT: return "INIT_IO_UNIT"; 674 | case MPI2_EVENT_PM_INIT_PCIE_DPA: return "INIT_PCIE_DPA"; 675 | } 676 | 677 | return "INIT_UNKNOWN"; 678 | } 679 | 680 | static const char *power_mode_mode_to_text(uint8_t val) 681 | { 682 | val &= MPI2_EVENT_PM_MODE_MASK; 683 | 684 | switch (val) { 685 | case MPI2_EVENT_PM_MODE_UNAVAILABLE: return "MODE_UNAVAILABLE"; 686 | case MPI2_EVENT_PM_MODE_UNKNOWN: return "MODE_UNKNOWN"; 687 | case MPI2_EVENT_PM_MODE_FULL_POWER: return "MODE_FULL_POWER"; 688 | case MPI2_EVENT_PM_MODE_REDUCED_POWER: return "MODE_REDUCED_POWER"; 689 | case MPI2_EVENT_PM_MODE_STANDBY: return "MODE_STANDBY"; 690 | } 691 | 692 | return "MODE_UNKNOWN_FALLOUT"; 693 | } 694 | 695 | static void dump_power_performance_change(struct MPT2_IOCTL_EVENTS *event) 696 | { 697 | MPI2_EVENT_DATA_POWER_PERF_CHANGE *evt = (void*)&event->data; 698 | 699 | my_syslog(LOG_INFO, "Power Performance Change: context=%u current_power_mode=%02X(%s %s) prev_power_mode=%02X(%s %s) reserved1=%04X", 700 | event->context, 701 | evt->CurrentPowerMode, power_mode_init_to_text(evt->CurrentPowerMode), power_mode_mode_to_text(evt->CurrentPowerMode), 702 | evt->PreviousPowerMode, power_mode_init_to_text(evt->PreviousPowerMode), power_mode_mode_to_text(evt->PreviousPowerMode), 703 | evt->Reserved1); 704 | } 705 | 706 | static void dump_event(struct MPT2_IOCTL_EVENTS *event, int ioc) 707 | { 708 | switch (event->event) { 709 | case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE: 710 | dump_sas_device_status_change(event, ioc); 711 | break; 712 | 713 | case MPI2_EVENT_LOG_DATA: 714 | dump_log_data(event); 715 | break; 716 | 717 | case MPI2_EVENT_GPIO_INTERRUPT: 718 | dump_gpio_interrupt(event); 719 | break; 720 | 721 | case MPI2_EVENT_STATE_CHANGE: 722 | dump_name_only("State Change", event); 723 | break; 724 | 725 | case MPI2_EVENT_HARD_RESET_RECEIVED: 726 | dump_hard_reset_received(event); 727 | break; 728 | 729 | case MPI2_EVENT_EVENT_CHANGE: 730 | dump_name_only("Event Change", event); 731 | break; 732 | 733 | case MPI2_EVENT_TASK_SET_FULL: 734 | dump_task_set_full(event); 735 | break; 736 | 737 | case MPI2_EVENT_IR_OPERATION_STATUS: 738 | dump_ir_operation_status(event); 739 | break; 740 | 741 | case MPI2_EVENT_SAS_DISCOVERY: 742 | dump_sas_discovery(event); 743 | break; 744 | 745 | case MPI2_EVENT_SAS_BROADCAST_PRIMITIVE: 746 | dump_sas_broadcast_primitive(event); 747 | break; 748 | 749 | case MPI2_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 750 | dump_sas_init_dev_status_change(event); 751 | break; 752 | 753 | case MPI2_EVENT_SAS_INIT_TABLE_OVERFLOW: 754 | dump_sas_init_table_overflow(event); 755 | break; 756 | 757 | case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 758 | dump_sas_topology_change_list(event); 759 | break; 760 | 761 | case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE: 762 | dump_sas_enclosure_device_status_change(event); 763 | break; 764 | 765 | case MPI2_EVENT_IR_VOLUME: 766 | dump_ir_volume(event); 767 | break; 768 | 769 | case MPI2_EVENT_IR_PHYSICAL_DISK: 770 | dump_ir_physical_disk(event); 771 | break; 772 | 773 | case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST: 774 | dump_ir_config_change_list(event); 775 | break; 776 | 777 | case MPI2_EVENT_LOG_ENTRY_ADDED: 778 | dump_name_only("Log Entry Added", event); 779 | break; 780 | 781 | case MPI2_EVENT_SAS_PHY_COUNTER: 782 | dump_sas_phy_counter(event); 783 | break; 784 | 785 | case MPI2_EVENT_HOST_BASED_DISCOVERY_PHY: 786 | dump_name_only("Host Based Discovery Phy", event); 787 | break; 788 | 789 | case MPI2_EVENT_SAS_QUIESCE: 790 | dump_sas_quiesce(event); 791 | break; 792 | 793 | case MPI2_EVENT_SAS_NOTIFY_PRIMITIVE: 794 | dump_sas_notify_primitive(event); 795 | break; 796 | 797 | case MPI2_EVENT_TEMP_THRESHOLD: 798 | dump_temperature_threshold(event); 799 | break; 800 | 801 | case MPI2_EVENT_HOST_MESSAGE: 802 | dump_name_only("Host Message", event); 803 | break; 804 | 805 | case MPI2_EVENT_POWER_PERFORMANCE_CHANGE: 806 | dump_power_performance_change(event); 807 | break; 808 | 809 | default: 810 | dump_name_only("Unknown Event", event); 811 | break; 812 | } 813 | } 814 | 815 | void dump_all_events(struct mpt_events *events, uint32_t *highest_context, int first_read) 816 | { 817 | int i; 818 | uint32_t new_context = *highest_context; 819 | 820 | for (i = 0; i < MPT2SAS_CTL_EVENT_LOG_SIZE; i++) { 821 | struct MPT2_IOCTL_EVENTS *event = &events->event_data[i]; 822 | 823 | if (!event->event) 824 | continue; 825 | 826 | /* Because we read the entire circular buffer we can get the highest 827 | * context before the older contexts that we didn't read yet. As such 828 | * we need to compare the context to the old context we had and only 829 | * replace it once we finished the read 830 | */ 831 | if (first_read || (int)(event->context - *highest_context) > 0) { 832 | dump_event(event, events->hdr.ioc_number); 833 | new_context = event->context; 834 | } 835 | } 836 | 837 | *highest_context = new_context; 838 | } 839 | --------------------------------------------------------------------------------