| 1 | /* $NetBSD: mpt_debug.c,v 1.11 2015/11/05 21:08:18 palle Exp $ */ |
| 2 | |
| 3 | /* |
| 4 | * Copyright (c) 2000, 2001 by Greg Ansley |
| 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without |
| 7 | * modification, are permitted provided that the following conditions |
| 8 | * are met: |
| 9 | * 1. Redistributions of source code must retain the above copyright |
| 10 | * notice immediately at the beginning of the file, without modification, |
| 11 | * this list of conditions, and the following disclaimer. |
| 12 | * 2. The name of the author may not be used to endorse or promote products |
| 13 | * derived from this software without specific prior written permission. |
| 14 | * |
| 15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| 16 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 17 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 18 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR |
| 19 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 20 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 21 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 22 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 23 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 24 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 25 | * SUCH DAMAGE. |
| 26 | */ |
| 27 | /* |
| 28 | * Additional Copyright (c) 2002 by Matthew Jacob under same license. |
| 29 | */ |
| 30 | |
| 31 | /* |
| 32 | * mpt_debug.c: |
| 33 | * |
| 34 | * Debug routines for LSI Fusion adapters. |
| 35 | */ |
| 36 | |
| 37 | #include <sys/cdefs.h> |
| 38 | __KERNEL_RCSID(0, "$NetBSD: mpt_debug.c,v 1.11 2015/11/05 21:08:18 palle Exp $" ); |
| 39 | |
| 40 | #include <dev/ic/mpt.h> |
| 41 | |
| 42 | struct Error_Map { |
| 43 | int Error_Code; |
| 44 | const char *Error_String; |
| 45 | }; |
| 46 | |
| 47 | static const struct Error_Map IOC_Status[] = { |
| 48 | { MPI_IOCSTATUS_SUCCESS, "Success" }, |
| 49 | { MPI_IOCSTATUS_INVALID_FUNCTION, "IOC: Invalid Function" }, |
| 50 | { MPI_IOCSTATUS_BUSY, "IOC: Busy" }, |
| 51 | { MPI_IOCSTATUS_INVALID_SGL, "IOC: Invalid SGL" }, |
| 52 | { MPI_IOCSTATUS_INTERNAL_ERROR, "IOC: Internal Error" }, |
| 53 | { MPI_IOCSTATUS_RESERVED, "IOC: Reserved" }, |
| 54 | { MPI_IOCSTATUS_INSUFFICIENT_RESOURCES, "IOC: Insufficient Resources" }, |
| 55 | { MPI_IOCSTATUS_INVALID_FIELD, "IOC: Invalid Field" }, |
| 56 | { MPI_IOCSTATUS_INVALID_STATE, "IOC: Invalid State" }, |
| 57 | { MPI_IOCSTATUS_CONFIG_INVALID_ACTION, "Invalid Action" }, |
| 58 | { MPI_IOCSTATUS_CONFIG_INVALID_TYPE, "Invalid Type" }, |
| 59 | { MPI_IOCSTATUS_CONFIG_INVALID_PAGE, "Invalid Page" }, |
| 60 | { MPI_IOCSTATUS_CONFIG_INVALID_DATA, "Invalid Data" }, |
| 61 | { MPI_IOCSTATUS_CONFIG_NO_DEFAULTS, "No Defaults" }, |
| 62 | { MPI_IOCSTATUS_CONFIG_CANT_COMMIT, "Can't Commit" }, |
| 63 | { MPI_IOCSTATUS_SCSI_RECOVERED_ERROR, "SCSI: Recoverd Error" }, |
| 64 | { MPI_IOCSTATUS_SCSI_INVALID_BUS, "SCSI: Invalid Bus" }, |
| 65 | { MPI_IOCSTATUS_SCSI_INVALID_TARGETID, "SCSI: Invalid Target ID" }, |
| 66 | { MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE, "SCSI: Device Not There" }, |
| 67 | { MPI_IOCSTATUS_SCSI_DATA_OVERRUN, "SCSI: Data Overrun" }, |
| 68 | { MPI_IOCSTATUS_SCSI_DATA_UNDERRUN, "SCSI: Data Underrun" }, |
| 69 | { MPI_IOCSTATUS_SCSI_IO_DATA_ERROR, "SCSI: Data Error" }, |
| 70 | { MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR, "SCSI: Protocol Error" }, |
| 71 | { MPI_IOCSTATUS_SCSI_TASK_TERMINATED, "SCSI: Task Terminated" }, |
| 72 | { MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH, "SCSI: Residual Mismatch" }, |
| 73 | { MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED, "SCSI: Task Management Failed" }, |
| 74 | { MPI_IOCSTATUS_SCSI_IOC_TERMINATED, "SCSI: IOC Bus Reset" }, |
| 75 | { MPI_IOCSTATUS_SCSI_EXT_TERMINATED, "SCSI: External Bus Reset" }, |
| 76 | { MPI_IOCSTATUS_TARGET_PRIORITY_IO, "SCSI Target: Priority I/O" }, |
| 77 | { MPI_IOCSTATUS_TARGET_INVALID_PORT, "SCSI Target: Invalid Port" }, |
| 78 | { MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX, "SCSI Target: Invalid IOC Index" }, |
| 79 | { MPI_IOCSTATUS_TARGET_ABORTED, "SCSI Target: Aborted" }, |
| 80 | { MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE, "SCSI Target: No Connection (Retryable)" }, |
| 81 | { MPI_IOCSTATUS_TARGET_NO_CONNECTION, "SCSI Target: No Connection" }, |
| 82 | { MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH,"SCSI Target: Transfer Count Mismatch" }, |
| 83 | { MPI_IOCSTATUS_TARGET_FC_ABORTED, "FC: Aborted" }, |
| 84 | { MPI_IOCSTATUS_TARGET_FC_RX_ID_INVALID, "FC: Receive ID Invalid" }, |
| 85 | { MPI_IOCSTATUS_TARGET_FC_DID_INVALID, "FC: Receive DID Invalid" }, |
| 86 | { MPI_IOCSTATUS_TARGET_FC_NODE_LOGGED_OUT,"FC: Node Logged Out" }, |
| 87 | { MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND, "LAN: Device Not Found" }, |
| 88 | { MPI_IOCSTATUS_LAN_DEVICE_FAILURE, "LAN: Device Not Failure" }, |
| 89 | { MPI_IOCSTATUS_LAN_TRANSMIT_ERROR, "LAN: Transmit Error" }, |
| 90 | { MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED, "LAN: Transmit Aborted" }, |
| 91 | { MPI_IOCSTATUS_LAN_RECEIVE_ERROR, "LAN: Receive Error" }, |
| 92 | { MPI_IOCSTATUS_LAN_RECEIVE_ABORTED, "LAN: Receive Aborted" }, |
| 93 | { MPI_IOCSTATUS_LAN_PARTIAL_PACKET, "LAN: Partial Packet" }, |
| 94 | { MPI_IOCSTATUS_LAN_CANCELED, "LAN: Canceled" }, |
| 95 | { -1, 0}, |
| 96 | }; |
| 97 | |
| 98 | static const struct Error_Map IOC_Func[] = { |
| 99 | { MPI_FUNCTION_SCSI_IO_REQUEST, "SCSI IO Request" }, |
| 100 | { MPI_FUNCTION_SCSI_TASK_MGMT, "SCSI Task Management" }, |
| 101 | { MPI_FUNCTION_IOC_INIT, "IOC Init" }, |
| 102 | { MPI_FUNCTION_IOC_FACTS, "IOC Facts" }, |
| 103 | { MPI_FUNCTION_CONFIG, "Config" }, |
| 104 | { MPI_FUNCTION_PORT_FACTS, "Port Facts" }, |
| 105 | { MPI_FUNCTION_PORT_ENABLE, "Port Enable" }, |
| 106 | { MPI_FUNCTION_EVENT_NOTIFICATION, "Event Notification" }, |
| 107 | { MPI_FUNCTION_FW_DOWNLOAD, "FW Download" }, |
| 108 | { MPI_FUNCTION_TARGET_CMD_BUFFER_POST, "SCSI Target Command Buffer" }, |
| 109 | { MPI_FUNCTION_TARGET_ASSIST, "Target Assist" }, |
| 110 | { MPI_FUNCTION_TARGET_STATUS_SEND, "Target Status Send" }, |
| 111 | { MPI_FUNCTION_TARGET_MODE_ABORT, "Target Mode Abort" }, |
| 112 | { MPI_FUNCTION_TARGET_FC_BUF_POST_LINK_SRVC, "FC: Link Service Buffers" }, |
| 113 | { MPI_FUNCTION_TARGET_FC_RSP_LINK_SRVC, "FC: Link Service Response" }, |
| 114 | { MPI_FUNCTION_TARGET_FC_EX_SEND_LINK_SRVC, "FC: Send Extended Link Service" }, |
| 115 | { MPI_FUNCTION_TARGET_FC_ABORT, "FC: Abort" }, |
| 116 | { MPI_FUNCTION_LAN_SEND, "LAN Send" }, |
| 117 | { MPI_FUNCTION_LAN_RECEIVE, "LAN Receive" }, |
| 118 | { MPI_FUNCTION_LAN_RESET, "LAN Reset" }, |
| 119 | { -1, 0}, |
| 120 | }; |
| 121 | |
| 122 | static const struct Error_Map IOC_Event[] = { |
| 123 | { MPI_EVENT_NONE, "None" }, |
| 124 | { MPI_EVENT_LOG_DATA, "LogData" }, |
| 125 | { MPI_EVENT_STATE_CHANGE, "State Change" }, |
| 126 | { MPI_EVENT_UNIT_ATTENTION, "Unit Attention" }, |
| 127 | { MPI_EVENT_IOC_BUS_RESET, "IOC Bus Reset" }, |
| 128 | { MPI_EVENT_EXT_BUS_RESET, "External Bus Reset" }, |
| 129 | { MPI_EVENT_RESCAN, "Rescan" }, |
| 130 | { MPI_EVENT_LINK_STATUS_CHANGE, "Link Status Change" }, |
| 131 | { MPI_EVENT_LOOP_STATE_CHANGE, "Loop State Change" }, |
| 132 | { MPI_EVENT_LOGOUT, "Logout" }, |
| 133 | { MPI_EVENT_EVENT_CHANGE, "EventChange" }, |
| 134 | { MPI_EVENT_INTEGRATED_RAID, "Integrated RAID" }, |
| 135 | { MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE, "SCSI Device Status Change" }, |
| 136 | { MPI_EVENT_ON_BUS_TIMER_EXPIRED, "On Bus Timer Expired" }, |
| 137 | { MPI_EVENT_QUEUE_FULL, "Queue Full" }, |
| 138 | { MPI_EVENT_SAS_DEVICE_STATUS_CHANGE, "SAS Device Status Change" }, |
| 139 | { MPI_EVENT_SAS_SES, "SAS Ses" }, |
| 140 | { MPI_EVENT_PERSISTENT_TABLE_FULL, "Persistent Table Full" }, |
| 141 | { MPI_EVENT_SAS_PHY_LINK_STATUS, "SAS Phy Link Status" }, |
| 142 | { MPI_EVENT_SAS_DISCOVERY_ERROR, "SAS Discovery Error" }, |
| 143 | { MPI_EVENT_IR_RESYNC_UPDATE, "IR Resync Update" }, |
| 144 | { MPI_EVENT_IR2, "IR2" , }, |
| 145 | { MPI_EVENT_SAS_DISCOVERY, "Sas Discovery" }, |
| 146 | { -1, 0}, |
| 147 | }; |
| 148 | |
| 149 | static const struct Error_Map IOC_SCSIState[] = { |
| 150 | { MPI_SCSI_STATE_AUTOSENSE_VALID, "AutoSense_Valid" }, |
| 151 | { MPI_SCSI_STATE_AUTOSENSE_FAILED, "AutoSense_Failed" }, |
| 152 | { MPI_SCSI_STATE_NO_SCSI_STATUS, "No_SCSI_Status" }, |
| 153 | { MPI_SCSI_STATE_TERMINATED, "State_Terminated" }, |
| 154 | { MPI_SCSI_STATE_RESPONSE_INFO_VALID, "Repsonse_Info_Valid" }, |
| 155 | { MPI_SCSI_STATE_QUEUE_TAG_REJECTED, "Queue Tag Rejected" }, |
| 156 | { -1, 0}, |
| 157 | }; |
| 158 | |
| 159 | static const struct Error_Map IOC_SCSIStatus[] = { |
| 160 | { SCSI_OK, "OK" }, |
| 161 | { SCSI_CHECK, "Check Condition" }, |
| 162 | #if 0 |
| 163 | { SCSI_STATUS_COND_MET, "Check Condition Met" }, |
| 164 | #endif |
| 165 | { SCSI_BUSY, "Busy" }, |
| 166 | { SCSI_INTERM, "Intermidiate Condition" }, |
| 167 | #if 0 |
| 168 | { SCSI_STATUS_INTERMED_COND_MET, "Intermidiate Condition Met" }, |
| 169 | #endif |
| 170 | { SCSI_RESV_CONFLICT, "Reservation Conflict" }, |
| 171 | #if 0 |
| 172 | { SCSI_STATUS_CMD_TERMINATED, "Command Terminated" }, |
| 173 | #endif |
| 174 | { SCSI_QUEUE_FULL, "Queue Full" }, |
| 175 | { -1, 0}, |
| 176 | }; |
| 177 | |
| 178 | static const struct Error_Map IOC_Diag[] = { |
| 179 | { MPT_DIAG_ENABLED, "DWE" }, |
| 180 | { MPT_DIAG_FLASHBAD, "FLASH_Bad" }, |
| 181 | { MPT_DIAG_TTLI, "TTLI" }, |
| 182 | { MPT_DIAG_RESET_IOC, "Reset" }, |
| 183 | { MPT_DIAG_ARM_DISABLE, "DisARM" }, |
| 184 | { MPT_DIAG_DME, "DME" }, |
| 185 | { -1, 0 }, |
| 186 | }; |
| 187 | |
| 188 | |
| 189 | static void mpt_dump_sgl(SGE_IO_UNION *sgl); |
| 190 | |
| 191 | static const char * |
| 192 | mpt_ioc_status(int code) |
| 193 | { |
| 194 | const struct Error_Map *status = IOC_Status; |
| 195 | static char tbuf[64]; |
| 196 | while (status->Error_Code >= 0) { |
| 197 | if (status->Error_Code == (code & MPI_IOCSTATUS_MASK)) |
| 198 | return status->Error_String; |
| 199 | status++; |
| 200 | } |
| 201 | snprintf(tbuf, sizeof tbuf, "Unknown (0x%08x)" , code); |
| 202 | return tbuf; |
| 203 | } |
| 204 | |
| 205 | char * |
| 206 | mpt_ioc_diag(u_int32_t code) |
| 207 | { |
| 208 | const struct Error_Map *status = IOC_Diag; |
| 209 | static char tbuf[128]; |
| 210 | size_t len; |
| 211 | len = snprintf(tbuf, sizeof(tbuf), "(0x%08x)" , code); |
| 212 | if (len > sizeof(tbuf)) |
| 213 | return tbuf; |
| 214 | while (status->Error_Code >= 0) { |
| 215 | if ((status->Error_Code & code) != 0) { |
| 216 | if (len >= sizeof(tbuf)) |
| 217 | return tbuf; |
| 218 | len += snprintf(tbuf + len, sizeof(tbuf) - len, "%s " , |
| 219 | status->Error_String); |
| 220 | } |
| 221 | status++; |
| 222 | } |
| 223 | return tbuf; |
| 224 | } |
| 225 | |
| 226 | static const char * |
| 227 | mpt_ioc_function(int code) |
| 228 | { |
| 229 | const struct Error_Map *status = IOC_Func; |
| 230 | static char tbuf[64]; |
| 231 | while (status->Error_Code >= 0) { |
| 232 | if (status->Error_Code == code) |
| 233 | return status->Error_String; |
| 234 | status++; |
| 235 | } |
| 236 | snprintf(tbuf, sizeof tbuf, "Unknown (0x%08x)" , code); |
| 237 | return tbuf; |
| 238 | } |
| 239 | static const char * |
| 240 | mpt_ioc_event(int code) |
| 241 | { |
| 242 | const struct Error_Map *status = IOC_Event; |
| 243 | static char tbuf[64]; |
| 244 | while (status->Error_Code >= 0) { |
| 245 | if (status->Error_Code == code) |
| 246 | return status->Error_String; |
| 247 | status++; |
| 248 | } |
| 249 | snprintf(tbuf, sizeof tbuf, "Unknown (0x%08x)" , code); |
| 250 | return tbuf; |
| 251 | } |
| 252 | static char * |
| 253 | mpt_scsi_state(int code) |
| 254 | { |
| 255 | const struct Error_Map *status = IOC_SCSIState; |
| 256 | static char tbuf[128]; |
| 257 | size_t len; |
| 258 | len = snprintf(tbuf, sizeof(tbuf), "(0x%08x)" , code); |
| 259 | if (len > sizeof(tbuf)) |
| 260 | return tbuf; |
| 261 | while (status->Error_Code >= 0) { |
| 262 | if ((status->Error_Code & code) != 0) { |
| 263 | if (len >= sizeof(tbuf)) |
| 264 | return tbuf; |
| 265 | len += snprintf(tbuf + len, sizeof(tbuf) - len, "%s " , |
| 266 | status->Error_String); |
| 267 | } |
| 268 | status++; |
| 269 | } |
| 270 | return tbuf; |
| 271 | } |
| 272 | static const char * |
| 273 | mpt_scsi_status(int code) |
| 274 | { |
| 275 | const struct Error_Map *status = IOC_SCSIStatus; |
| 276 | static char tbuf[64]; |
| 277 | while (status->Error_Code >= 0) { |
| 278 | if (status->Error_Code == code) |
| 279 | return status->Error_String; |
| 280 | status++; |
| 281 | } |
| 282 | snprintf(tbuf, sizeof tbuf, "Unknown (0x%08x)" , code); |
| 283 | return tbuf; |
| 284 | } |
| 285 | static const char * |
| 286 | mpt_who(int who_init) |
| 287 | { |
| 288 | const char *who; |
| 289 | |
| 290 | switch (who_init) { |
| 291 | case MPT_DB_INIT_NOONE: who = "No One" ; break; |
| 292 | case MPT_DB_INIT_BIOS: who = "BIOS" ; break; |
| 293 | case MPT_DB_INIT_ROMBIOS: who = "ROM BIOS" ; break; |
| 294 | case MPT_DB_INIT_PCIPEER: who = "PCI Peer" ; break; |
| 295 | case MPT_DB_INIT_HOST: who = "Host Driver" ; break; |
| 296 | case MPT_DB_INIT_MANUFACTURE: who = "Manufacturing" ; break; |
| 297 | default: who = "Unknown" ; break; |
| 298 | } |
| 299 | return who; |
| 300 | } |
| 301 | |
| 302 | static const char * |
| 303 | mpt_state(u_int32_t mb) |
| 304 | { |
| 305 | const char *text; |
| 306 | |
| 307 | switch (MPT_STATE(mb)) { |
| 308 | case MPT_DB_STATE_RESET: text = "Reset" ; break; |
| 309 | case MPT_DB_STATE_READY: text = "Ready" ; break; |
| 310 | case MPT_DB_STATE_RUNNING:text = "Running" ; break; |
| 311 | case MPT_DB_STATE_FAULT: text = "Fault" ; break; |
| 312 | default: text = "Unknown" ; break; |
| 313 | } |
| 314 | return text; |
| 315 | }; |
| 316 | |
| 317 | void |
| 318 | mpt_print_db(u_int32_t mb) |
| 319 | { |
| 320 | printf("mpt mailbox: (0x%x) State %s WhoInit %s\n" , |
| 321 | mb, mpt_state(mb), mpt_who(MPT_WHO(mb))); |
| 322 | } |
| 323 | |
| 324 | /*****************************************************************************/ |
| 325 | /* Reply functions */ |
| 326 | /*****************************************************************************/ |
| 327 | static void |
| 328 | mpt_print_reply_hdr(MSG_DEFAULT_REPLY *msg) |
| 329 | { |
| 330 | printf("%s Reply @ %p\n" , mpt_ioc_function(msg->Function), msg); |
| 331 | printf("\tIOC Status %s\n" , mpt_ioc_status(le16toh(msg->IOCStatus))); |
| 332 | printf("\tIOCLogInfo 0x%08x\n" , msg->IOCLogInfo); |
| 333 | printf("\tMsgLength 0x%02x\n" , msg->MsgLength); |
| 334 | printf("\tMsgFlags 0x%02x\n" , msg->MsgFlags); |
| 335 | printf("\tMsgContext 0x%08x\n" , le32toh(msg->MsgContext)); |
| 336 | } |
| 337 | |
| 338 | static void |
| 339 | mpt_print_init_reply(MSG_IOC_INIT_REPLY *msg) |
| 340 | { |
| 341 | mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); |
| 342 | printf("\tWhoInit %s\n" , mpt_who(msg->WhoInit)); |
| 343 | printf("\tMaxDevices 0x%02x\n" , msg->MaxDevices); |
| 344 | printf("\tMaxBuses 0x%02x\n" , msg->MaxBuses); |
| 345 | } |
| 346 | |
| 347 | static void |
| 348 | mpt_print_ioc_facts(MSG_IOC_FACTS_REPLY *msg) |
| 349 | { |
| 350 | mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); |
| 351 | printf("\tIOCNumber %d\n" , msg->IOCNumber); |
| 352 | printf("\tMaxChainDepth %d\n" , msg->MaxChainDepth); |
| 353 | printf("\tWhoInit %s\n" , mpt_who(msg->WhoInit)); |
| 354 | printf("\tBlockSize %d\n" , msg->BlockSize); |
| 355 | printf("\tFlags %d\n" , msg->Flags); |
| 356 | printf("\tReplyQueueDepth %d\n" , le16toh(msg->ReplyQueueDepth)); |
| 357 | printf("\tReqFrameSize 0x%04x\n" , le16toh(msg->RequestFrameSize)); |
| 358 | printf("\tFW Version 0x%08x\n" , msg->FWVersion.Word); |
| 359 | printf("\tProduct ID 0x%04x\n" , le16toh(msg->ProductID)); |
| 360 | printf("\tCredits 0x%04x\n" , le16toh(msg->GlobalCredits)); |
| 361 | printf("\tPorts %d\n" , msg->NumberOfPorts); |
| 362 | printf("\tEventState 0x%02x\n" , msg->EventState); |
| 363 | printf("\tHostMFA_HA 0x%08x\n" , |
| 364 | le32toh(msg->CurrentHostMfaHighAddr)); |
| 365 | printf("\tSenseBuf_HA 0x%08x\n" , |
| 366 | le32toh(msg->CurrentSenseBufferHighAddr)); |
| 367 | printf("\tRepFrameSize 0x%04x\n" , |
| 368 | le16toh(msg->CurReplyFrameSize)); |
| 369 | printf("\tMaxDevices 0x%02x\n" , msg->MaxDevices); |
| 370 | printf("\tMaxBuses 0x%02x\n" , msg->MaxBuses); |
| 371 | printf("\tFWImageSize 0x%04x\n" , le32toh(msg->FWImageSize)); |
| 372 | } |
| 373 | |
| 374 | static void |
| 375 | mpt_print_enable_reply(MSG_PORT_ENABLE_REPLY *msg) |
| 376 | { |
| 377 | mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); |
| 378 | printf("\tPort: %d\n" , msg->PortNumber); |
| 379 | } |
| 380 | |
| 381 | static void |
| 382 | mpt_print_scsi_io_reply(MSG_SCSI_IO_REPLY *msg) |
| 383 | { |
| 384 | mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); |
| 385 | printf("\tBus: %d\n" , msg->Bus); |
| 386 | printf("\tTargetID %d\n" , msg->TargetID); |
| 387 | printf("\tCDBLength %d\n" , msg->CDBLength); |
| 388 | printf("\tSCSI Status: %s\n" , mpt_scsi_status(msg->SCSIStatus)); |
| 389 | printf("\tSCSI State: %s\n" , mpt_scsi_state(msg->SCSIState)); |
| 390 | printf("\tTransferCnt 0x%04x\n" , le32toh(msg->TransferCount)); |
| 391 | printf("\tSenseCnt 0x%04x\n" , le32toh(msg->SenseCount)); |
| 392 | printf("\tResponseInfo 0x%08x\n" , le32toh(msg->ResponseInfo)); |
| 393 | } |
| 394 | |
| 395 | |
| 396 | |
| 397 | static void |
| 398 | mpt_print_event_notice(MSG_EVENT_NOTIFY_REPLY *msg) |
| 399 | { |
| 400 | mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); |
| 401 | printf("\tEvent: %s\n" , mpt_ioc_event(le32toh(msg->Event))); |
| 402 | printf("\tEventContext 0x%04x\n" , le32toh(msg->EventContext)); |
| 403 | printf("\tAckRequired %d\n" , msg->AckRequired); |
| 404 | printf("\tEventDataLength %d\n" , le16toh(msg->EventDataLength)); |
| 405 | printf("\tContinuation %d\n" , msg->MsgFlags & 0x80); |
| 406 | switch(msg->Event) { |
| 407 | case MPI_EVENT_LOG_DATA: |
| 408 | printf("\tEvtLogData: 0x%04x\n" , le32toh(msg->Data[0])); |
| 409 | break; |
| 410 | |
| 411 | case MPI_EVENT_UNIT_ATTENTION: |
| 412 | printf("\tTargetID: 0x%04x\n" , |
| 413 | msg->Data[0] & 0xff); |
| 414 | printf("\tBus: 0x%04x\n" , |
| 415 | (msg->Data[0] >> 8) & 0xff); |
| 416 | break; |
| 417 | |
| 418 | case MPI_EVENT_IOC_BUS_RESET: |
| 419 | case MPI_EVENT_EXT_BUS_RESET: |
| 420 | case MPI_EVENT_RESCAN: |
| 421 | printf("\tPort: %d\n" , |
| 422 | (msg->Data[0] >> 8) & 0xff); |
| 423 | break; |
| 424 | |
| 425 | case MPI_EVENT_LINK_STATUS_CHANGE: |
| 426 | printf("\tLinkState: %d\n" , |
| 427 | msg->Data[0] & 0xff); |
| 428 | printf("\tPort: %d\n" , |
| 429 | (msg->Data[1] >> 8) & 0xff); |
| 430 | break; |
| 431 | |
| 432 | case MPI_EVENT_LOOP_STATE_CHANGE: |
| 433 | printf("\tType: %d\n" , |
| 434 | (msg->Data[0] >> 16) & 0xff); |
| 435 | printf("\tChar3: 0x%02x\n" , |
| 436 | (msg->Data[0] >> 8) & 0xff); |
| 437 | printf("\tChar4: 0x%02x\n" , |
| 438 | (msg->Data[0] ) & 0xff); |
| 439 | printf("\tPort: %d\n" , |
| 440 | (msg->Data[1] >> 8) & 0xff); |
| 441 | break; |
| 442 | |
| 443 | case MPI_EVENT_LOGOUT: |
| 444 | printf("\tN_PortId: 0x%04x\n" , msg->Data[0]); |
| 445 | printf("\tPort: %d\n" , |
| 446 | (msg->Data[1] >> 8) & 0xff); |
| 447 | break; |
| 448 | } |
| 449 | |
| 450 | } |
| 451 | |
| 452 | void |
| 453 | mpt_print_reply(void *vmsg) |
| 454 | { |
| 455 | MSG_DEFAULT_REPLY *msg = vmsg; |
| 456 | |
| 457 | switch (msg->Function) { |
| 458 | case MPI_FUNCTION_EVENT_NOTIFICATION: |
| 459 | mpt_print_event_notice((MSG_EVENT_NOTIFY_REPLY *)msg); |
| 460 | break; |
| 461 | case MPI_FUNCTION_PORT_ENABLE: |
| 462 | mpt_print_enable_reply((MSG_PORT_ENABLE_REPLY *)msg); |
| 463 | break; |
| 464 | case MPI_FUNCTION_IOC_FACTS: |
| 465 | mpt_print_ioc_facts((MSG_IOC_FACTS_REPLY *)msg); |
| 466 | break; |
| 467 | case MPI_FUNCTION_IOC_INIT: |
| 468 | mpt_print_init_reply((MSG_IOC_INIT_REPLY *)msg); |
| 469 | break; |
| 470 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
| 471 | mpt_print_scsi_io_reply((MSG_SCSI_IO_REPLY *)msg); |
| 472 | break; |
| 473 | default: |
| 474 | mpt_print_reply_hdr((MSG_DEFAULT_REPLY *)msg); |
| 475 | break; |
| 476 | } |
| 477 | } |
| 478 | |
| 479 | /*****************************************************************************/ |
| 480 | /* Request functions */ |
| 481 | /*****************************************************************************/ |
| 482 | static void |
| 483 | mpt_print_request_hdr(MSG_REQUEST_HEADER *req) |
| 484 | { |
| 485 | printf("%s @ %p\n" , mpt_ioc_function(req->Function), req); |
| 486 | printf("\tChain Offset 0x%02x\n" , req->ChainOffset); |
| 487 | printf("\tMsgFlags 0x%02x\n" , req->MsgFlags); |
| 488 | printf("\tMsgContext 0x%08x\n" , le32toh(req->MsgContext)); |
| 489 | } |
| 490 | |
| 491 | void |
| 492 | mpt_print_scsi_io_request(MSG_SCSI_IO_REQUEST *orig_msg) |
| 493 | { |
| 494 | MSG_SCSI_IO_REQUEST local, *msg = &local; |
| 495 | int i; |
| 496 | |
| 497 | memcpy(msg, orig_msg, sizeof (MSG_SCSI_IO_REQUEST)); |
| 498 | mpt_print_request_hdr((MSG_REQUEST_HEADER *)msg); |
| 499 | printf("\tBus: %d\n" , msg->Bus); |
| 500 | printf("\tTargetID %d\n" , msg->TargetID); |
| 501 | printf("\tSenseBufferLength %d\n" , msg->SenseBufferLength); |
| 502 | printf("\tLUN: 0x%0x\n" , msg->LUN[1]); |
| 503 | printf("\tControl 0x%08x " , le32toh(msg->Control)); |
| 504 | #define MPI_PRINT_FIELD(x) \ |
| 505 | case MPI_SCSIIO_CONTROL_ ## x : \ |
| 506 | printf(" " #x " "); \ |
| 507 | break |
| 508 | |
| 509 | switch (le32toh(msg->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK) { |
| 510 | MPI_PRINT_FIELD(NODATATRANSFER); |
| 511 | MPI_PRINT_FIELD(WRITE); |
| 512 | MPI_PRINT_FIELD(READ); |
| 513 | default: |
| 514 | printf(" Invalid DIR! " ); |
| 515 | break; |
| 516 | } |
| 517 | switch (le32toh(msg->Control) & MPI_SCSIIO_CONTROL_TASKATTRIBUTE_MASK) { |
| 518 | MPI_PRINT_FIELD(SIMPLEQ); |
| 519 | MPI_PRINT_FIELD(HEADOFQ); |
| 520 | MPI_PRINT_FIELD(ORDEREDQ); |
| 521 | MPI_PRINT_FIELD(ACAQ); |
| 522 | MPI_PRINT_FIELD(UNTAGGED); |
| 523 | MPI_PRINT_FIELD(NO_DISCONNECT); |
| 524 | default: |
| 525 | printf(" Unknown attribute! " ); |
| 526 | break; |
| 527 | } |
| 528 | |
| 529 | printf("\n" ); |
| 530 | #undef MPI_PRINT_FIELD |
| 531 | |
| 532 | printf("\tDataLength\t0x%08x\n" , le32toh(msg->DataLength)); |
| 533 | printf("\tSenseBufAddr\t0x%08x\n" , le32toh(msg->SenseBufferLowAddr)); |
| 534 | printf("\tCDB[0:%d]\t" , msg->CDBLength); |
| 535 | for (i = 0; i < msg->CDBLength; i++) |
| 536 | printf("%02x " , msg->CDB[i]); |
| 537 | printf("\n" ); |
| 538 | mpt_dump_sgl(&orig_msg->SGL); |
| 539 | } |
| 540 | |
| 541 | void |
| 542 | mpt_print_request(void *vreq) |
| 543 | { |
| 544 | MSG_REQUEST_HEADER *req = vreq; |
| 545 | |
| 546 | switch (req->Function) { |
| 547 | case MPI_FUNCTION_SCSI_IO_REQUEST: |
| 548 | mpt_print_scsi_io_request((MSG_SCSI_IO_REQUEST *)req); |
| 549 | break; |
| 550 | default: |
| 551 | mpt_print_request_hdr(req); |
| 552 | break; |
| 553 | } |
| 554 | } |
| 555 | |
| 556 | const char * |
| 557 | mpt_req_state(enum mpt_req_state state) |
| 558 | { |
| 559 | const char *text; |
| 560 | |
| 561 | switch (state) { |
| 562 | case REQ_FREE: text = "Free" ; break; |
| 563 | case REQ_IN_PROGRESS: text = "In Progress" ; break; |
| 564 | case REQ_ON_CHIP: text = "On Chip" ; break; |
| 565 | case REQ_TIMEOUT: text = "Timeout" ; break; |
| 566 | default: text = "Unknown" ; break; |
| 567 | } |
| 568 | return text; |
| 569 | }; |
| 570 | |
| 571 | static void |
| 572 | mpt_dump_sgl(SGE_IO_UNION *su) |
| 573 | { |
| 574 | SGE_SIMPLE32 *se = (SGE_SIMPLE32 *) su; |
| 575 | int iCount, flags; |
| 576 | |
| 577 | iCount = MPT_SGL_MAX; |
| 578 | do { |
| 579 | int iprt; |
| 580 | |
| 581 | printf("\t" ); |
| 582 | flags = MPI_SGE_GET_FLAGS(le32toh(se->FlagsLength)); |
| 583 | switch (flags & MPI_SGE_FLAGS_ELEMENT_MASK) { |
| 584 | case MPI_SGE_FLAGS_SIMPLE_ELEMENT: |
| 585 | { |
| 586 | printf("SE32 %p: Addr=0x%0x FlagsLength=0x%0x\n" , |
| 587 | se, le32toh(se->Address), le32toh(se->FlagsLength)); |
| 588 | printf(" " ); |
| 589 | break; |
| 590 | } |
| 591 | case MPI_SGE_FLAGS_CHAIN_ELEMENT: |
| 592 | { |
| 593 | SGE_CHAIN32 *ce = (SGE_CHAIN32 *) se; |
| 594 | printf("CE32 %p: Addr=0x%0x NxtChnO=0x%x Flgs=0x%x " |
| 595 | "Len=0x%0x\n" , ce, le32toh(ce->Address), |
| 596 | ce->NextChainOffset, ce->Flags, |
| 597 | le16toh(ce->Length)); |
| 598 | flags = 0; |
| 599 | break; |
| 600 | } |
| 601 | case MPI_SGE_FLAGS_TRANSACTION_ELEMENT: |
| 602 | printf("TE32 @ %p\n" , se); |
| 603 | flags = 0; |
| 604 | break; |
| 605 | } |
| 606 | iprt = 0; |
| 607 | #define MPT_PRINT_FLAG(x) \ |
| 608 | if (flags & MPI_SGE_FLAGS_ ## x ) { \ |
| 609 | if (iprt == 0) { \ |
| 610 | printf("\t"); \ |
| 611 | } \ |
| 612 | printf(" "); \ |
| 613 | printf( #x ); \ |
| 614 | iprt++; \ |
| 615 | } |
| 616 | MPT_PRINT_FLAG(LOCAL_ADDRESS); |
| 617 | MPT_PRINT_FLAG(HOST_TO_IOC); |
| 618 | MPT_PRINT_FLAG(64_BIT_ADDRESSING); |
| 619 | MPT_PRINT_FLAG(LAST_ELEMENT); |
| 620 | MPT_PRINT_FLAG(END_OF_BUFFER); |
| 621 | MPT_PRINT_FLAG(END_OF_LIST); |
| 622 | #undef MPT_PRINT_FLAG |
| 623 | if (iprt) |
| 624 | printf("\n" ); |
| 625 | se++; |
| 626 | iCount -= 1; |
| 627 | } while ((flags & MPI_SGE_FLAGS_END_OF_LIST) == 0 && iCount != 0); |
| 628 | } |
| 629 | |