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 | |