2 * Debug routines for LSI '909 FC adapters.
5 * Copyright (c) 2000, 2001 by Greg Ansley
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice immediately at the beginning of the file, without modification,
12 * this list of conditions, and the following disclaimer.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * Copyright (c) 2002, 2006 by Matthew Jacob
31 * All rights reserved.
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions are
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
39 * substantially similar to the "NO WARRANTY" disclaimer below
40 * ("Disclaimer") and any redistribution must be conditioned upon including
41 * a substantially similar Disclaimer requirement for further binary
43 * 3. Neither the names of the above listed copyright holders nor the names
44 * of any contributors may be used to endorse or promote products derived
45 * from this software without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT
57 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 * Support from Chris Ellsworth in order to make SAS adapters work
60 * is gratefully acknowledged.
62 * Support from LSI-Logic has also gone a great deal toward making this a
63 * workable subsystem and is gratefully acknowledged.
65 * $FreeBSD: head/sys/dev/mpt/mpt_debug.c 241874 2012-10-22 10:42:59Z marius $
68 #include <dev/disk/mpt/mpt.h>
70 #include <dev/disk/mpt/mpilib/mpi_ioc.h>
71 #include <dev/disk/mpt/mpilib/mpi_init.h>
72 #include <dev/disk/mpt/mpilib/mpi_fc.h>
73 #include <dev/disk/mpt/mpilib/mpi_targ.h>
75 #include <bus/cam/scsi/scsi_all.h>
77 #include <machine/stdarg.h> /* for use by mpt_prt below */
84 static const struct Error_Map IOC_Status
[] = {
85 { MPI_IOCSTATUS_SUCCESS
, "Success" },
86 { MPI_IOCSTATUS_INVALID_FUNCTION
, "IOC: Invalid Function" },
87 { MPI_IOCSTATUS_BUSY
, "IOC: Busy" },
88 { MPI_IOCSTATUS_INVALID_SGL
, "IOC: Invalid SGL" },
89 { MPI_IOCSTATUS_INTERNAL_ERROR
, "IOC: Internal Error" },
90 { MPI_IOCSTATUS_RESERVED
, "IOC: Reserved" },
91 { MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
, "IOC: Insufficient Resources" },
92 { MPI_IOCSTATUS_INVALID_FIELD
, "IOC: Invalid Field" },
93 { MPI_IOCSTATUS_INVALID_STATE
, "IOC: Invalid State" },
94 { MPI_IOCSTATUS_CONFIG_INVALID_ACTION
, "Invalid Action" },
95 { MPI_IOCSTATUS_CONFIG_INVALID_TYPE
, "Invalid Type" },
96 { MPI_IOCSTATUS_CONFIG_INVALID_PAGE
, "Invalid Page" },
97 { MPI_IOCSTATUS_CONFIG_INVALID_DATA
, "Invalid Data" },
98 { MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
, "No Defaults" },
99 { MPI_IOCSTATUS_CONFIG_CANT_COMMIT
, "Can't Commit" },
100 { MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
, "SCSI: Recoverd Error" },
101 { MPI_IOCSTATUS_SCSI_INVALID_BUS
, "SCSI: Invalid Bus" },
102 { MPI_IOCSTATUS_SCSI_INVALID_TARGETID
, "SCSI: Invalid Target ID" },
103 { MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
, "SCSI: Device Not There" },
104 { MPI_IOCSTATUS_SCSI_DATA_OVERRUN
, "SCSI: Data Overrun" },
105 { MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
, "SCSI: Data Underrun" },
106 { MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
, "SCSI: Data Error" },
107 { MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
, "SCSI: Protocol Error" },
108 { MPI_IOCSTATUS_SCSI_TASK_TERMINATED
, "SCSI: Task Terminated" },
109 { MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
, "SCSI: Residual Mismatch" },
110 { MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
, "SCSI: Task Management Failed" },
111 { MPI_IOCSTATUS_SCSI_IOC_TERMINATED
, "SCSI: IOC Bus Reset" },
112 { MPI_IOCSTATUS_SCSI_EXT_TERMINATED
, "SCSI: External Bus Reset" },
113 { MPI_IOCSTATUS_TARGET_PRIORITY_IO
, "SCSI Target: Priority I/O" },
114 { MPI_IOCSTATUS_TARGET_INVALID_PORT
, "SCSI Target: Invalid Port" },
115 { MPI_IOCSTATUS_TARGET_INVALID_IOCINDEX
, "SCSI Target: Invalid IOC Index" },
116 { MPI_IOCSTATUS_TARGET_ABORTED
, "SCSI Target: Aborted" },
117 { MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
, "SCSI Target: No Connection (Retryable)" },
118 { MPI_IOCSTATUS_TARGET_NO_CONNECTION
, "SCSI Target: No Connection" },
119 { MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
,"SCSI Target: Transfer Count Mismatch" },
120 { MPI_IOCSTATUS_TARGET_FC_ABORTED
, "FC: Aborted" },
121 { MPI_IOCSTATUS_TARGET_FC_RX_ID_INVALID
, "FC: Receive ID Invalid" },
122 { MPI_IOCSTATUS_TARGET_FC_DID_INVALID
, "FC: Receive DID Invalid" },
123 { MPI_IOCSTATUS_TARGET_FC_NODE_LOGGED_OUT
,"FC: Node Logged Out" },
124 { MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
, "LAN: Device Not Found" },
125 { MPI_IOCSTATUS_LAN_DEVICE_FAILURE
, "LAN: Device Not Failure" },
126 { MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
, "LAN: Transmit Error" },
127 { MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
, "LAN: Transmit Aborted" },
128 { MPI_IOCSTATUS_LAN_RECEIVE_ERROR
, "LAN: Receive Error" },
129 { MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
, "LAN: Receive Aborted" },
130 { MPI_IOCSTATUS_LAN_PARTIAL_PACKET
, "LAN: Partial Packet" },
131 { MPI_IOCSTATUS_LAN_CANCELED
, "LAN: Canceled" },
135 static const struct Error_Map IOC_Func
[] = {
136 { MPI_FUNCTION_SCSI_IO_REQUEST
, "SCSI IO Request" },
137 { MPI_FUNCTION_SCSI_TASK_MGMT
, "SCSI Task Management" },
138 { MPI_FUNCTION_IOC_INIT
, "IOC Init" },
139 { MPI_FUNCTION_IOC_FACTS
, "IOC Facts" },
140 { MPI_FUNCTION_CONFIG
, "Config" },
141 { MPI_FUNCTION_PORT_FACTS
, "Port Facts" },
142 { MPI_FUNCTION_PORT_ENABLE
, "Port Enable" },
143 { MPI_FUNCTION_EVENT_NOTIFICATION
, "Event Notification" },
144 { MPI_FUNCTION_EVENT_ACK
, "Event Ack" },
145 { MPI_FUNCTION_FW_DOWNLOAD
, "FW Download" },
146 { MPI_FUNCTION_TARGET_CMD_BUFFER_POST
, "SCSI Target Command Buffer" },
147 { MPI_FUNCTION_TARGET_ASSIST
, "Target Assist" },
148 { MPI_FUNCTION_TARGET_STATUS_SEND
, "Target Status Send" },
149 { MPI_FUNCTION_TARGET_MODE_ABORT
, "Target Mode Abort" },
153 static const struct Error_Map IOC_Event
[] = {
154 { MPI_EVENT_NONE
, "None" },
155 { MPI_EVENT_LOG_DATA
, "LogData" },
156 { MPI_EVENT_STATE_CHANGE
, "State Change" },
157 { MPI_EVENT_UNIT_ATTENTION
, "Unit Attention" },
158 { MPI_EVENT_IOC_BUS_RESET
, "IOC Bus Reset" },
159 { MPI_EVENT_EXT_BUS_RESET
, "External Bus Reset" },
160 { MPI_EVENT_RESCAN
, "Rescan" },
161 { MPI_EVENT_LINK_STATUS_CHANGE
, "Link Status Change" },
162 { MPI_EVENT_LOOP_STATE_CHANGE
, "Loop State Change" },
163 { MPI_EVENT_LOGOUT
, "Logout" },
164 { MPI_EVENT_EVENT_CHANGE
, "EventChange" },
168 static const struct Error_Map IOC_SCSIState
[] = {
169 { MPI_SCSI_STATE_AUTOSENSE_VALID
, "AutoSense_Valid" },
170 { MPI_SCSI_STATE_AUTOSENSE_FAILED
, "AutoSense_Failed" },
171 { MPI_SCSI_STATE_NO_SCSI_STATUS
, "No_SCSI_Status" },
172 { MPI_SCSI_STATE_TERMINATED
, "State_Terminated" },
173 { MPI_SCSI_STATE_RESPONSE_INFO_VALID
, "Repsonse_Info_Valid" },
174 { MPI_SCSI_STATE_QUEUE_TAG_REJECTED
, "Queue Tag Rejected" },
178 static const struct Error_Map IOC_SCSIStatus
[] = {
179 { SCSI_STATUS_OK
, "OK" },
180 { SCSI_STATUS_CHECK_COND
, "Check Condition" },
181 { SCSI_STATUS_COND_MET
, "Check Condition Met" },
182 { SCSI_STATUS_BUSY
, "Busy" },
183 { SCSI_STATUS_INTERMED
, "Intermidiate Condition" },
184 { SCSI_STATUS_INTERMED_COND_MET
, "Intermidiate Condition Met" },
185 { SCSI_STATUS_RESERV_CONFLICT
, "Reservation Conflict" },
186 { SCSI_STATUS_CMD_TERMINATED
, "Command Terminated" },
187 { SCSI_STATUS_QUEUE_FULL
, "Queue Full" },
191 static const struct Error_Map IOC_Diag
[] = {
192 { MPI_DIAG_DRWE
, "DWE" },
193 { MPI_DIAG_FLASH_BAD_SIG
, "FLASH_Bad" },
194 { MPI_DIAGNOSTIC_OFFSET
, "Offset" },
195 { MPI_DIAG_RESET_ADAPTER
, "Reset" },
196 { MPI_DIAG_DISABLE_ARM
, "DisARM" },
197 { MPI_DIAG_MEM_ENABLE
, "DME" },
201 static const struct Error_Map IOC_SCSITMType
[] = {
202 { MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
, "Abort Task" },
203 { MPI_SCSITASKMGMT_TASKTYPE_ABRT_TASK_SET
, "Abort Task Set" },
204 { MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
, "Target Reset" },
205 { MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
, "Reset Bus" },
206 { MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET
, "Logical Unit Reset" },
211 mpt_ioc_status(int code
)
213 const struct Error_Map
*status
= IOC_Status
;
215 while (status
->Error_Code
>= 0) {
216 if (status
->Error_Code
== (code
& MPI_IOCSTATUS_MASK
))
217 return status
->Error_String
;
220 ksnprintf(buf
, sizeof buf
, "Unknown (0x%08x)", code
);
225 mpt_ioc_diag(u_int32_t code
)
227 const struct Error_Map
*status
= IOC_Diag
;
228 static char buf
[128];
230 char *end
= &buf
[128];
232 ptr
+= ksnprintf(buf
, sizeof buf
, "(0x%08x)", code
);
233 while (status
->Error_Code
>= 0) {
234 if ((status
->Error_Code
& code
) != 0)
235 ptr
+= ksnprintf(ptr
, (size_t)(end
-ptr
), "%s ",
236 status
->Error_String
);
243 mpt_ioc_function(int code
)
245 const struct Error_Map
*status
= IOC_Func
;
247 while (status
->Error_Code
>= 0) {
248 if (status
->Error_Code
== code
)
249 return status
->Error_String
;
252 ksnprintf(buf
, sizeof buf
, "Unknown (0x%08x)", code
);
257 mpt_ioc_event(int code
)
259 const struct Error_Map
*status
= IOC_Event
;
261 while (status
->Error_Code
>= 0) {
262 if (status
->Error_Code
== code
)
263 return status
->Error_String
;
266 ksnprintf(buf
, sizeof buf
, "Unknown (0x%08x)", code
);
271 mpt_scsi_state(int code
)
273 const struct Error_Map
*status
= IOC_SCSIState
;
274 static char buf
[128];
276 char *end
= &buf
[128];
278 ptr
+= ksnprintf(buf
, sizeof buf
, "(0x%08x)", code
);
279 while (status
->Error_Code
>= 0) {
280 if ((status
->Error_Code
& code
) != 0)
281 ptr
+= ksnprintf(ptr
, (size_t)(end
-ptr
), "%s ",
282 status
->Error_String
);
289 mpt_scsi_status(int code
)
291 const struct Error_Map
*status
= IOC_SCSIStatus
;
293 while (status
->Error_Code
>= 0) {
294 if (status
->Error_Code
== code
)
295 return status
->Error_String
;
298 ksnprintf(buf
, sizeof buf
, "Unknown (0x%08x)", code
);
303 mpt_who(int who_init
)
308 case MPT_DB_INIT_NOONE
: who
= "No One"; break;
309 case MPT_DB_INIT_BIOS
: who
= "BIOS"; break;
310 case MPT_DB_INIT_ROMBIOS
: who
= "ROM BIOS"; break;
311 case MPT_DB_INIT_PCIPEER
: who
= "PCI Peer"; break;
312 case MPT_DB_INIT_HOST
: who
= "Host Driver"; break;
313 case MPT_DB_INIT_MANUFACTURE
: who
= "Manufacturing"; break;
314 default: who
= "Unknown"; break;
320 mpt_state(u_int32_t mb
)
324 switch (MPT_STATE(mb
)) {
325 case MPT_DB_STATE_RESET
: text
= "Reset"; break;
326 case MPT_DB_STATE_READY
: text
= "Ready"; break;
327 case MPT_DB_STATE_RUNNING
:text
= "Running"; break;
328 case MPT_DB_STATE_FAULT
: text
= "Fault"; break;
329 default: text
= "Unknown"; break;
335 mpt_scsi_tm_type(int code
)
337 const struct Error_Map
*status
= IOC_SCSITMType
;
339 while (status
->Error_Code
>= 0) {
340 if (status
->Error_Code
== code
)
341 return status
->Error_String
;
344 ksnprintf(buf
, sizeof buf
, "Unknown (0x%08x)", code
);
349 mpt_print_db(u_int32_t mb
)
352 kprintf("mpt mailbox: (0x%x) State %s WhoInit %s\n",
353 mb
, mpt_state(mb
), mpt_who(MPT_WHO(mb
)));
356 /*****************************************************************************/
357 /* Reply functions */
358 /*****************************************************************************/
360 mpt_print_reply_hdr(MSG_DEFAULT_REPLY
*msg
)
363 kprintf("%s Reply @ %p\n", mpt_ioc_function(msg
->Function
), msg
);
364 kprintf("\tIOC Status %s\n", mpt_ioc_status(msg
->IOCStatus
));
365 kprintf("\tIOCLogInfo 0x%08x\n", msg
->IOCLogInfo
);
366 kprintf("\tMsgLength 0x%02x\n", msg
->MsgLength
);
367 kprintf("\tMsgFlags 0x%02x\n", msg
->MsgFlags
);
368 kprintf("\tMsgContext 0x%08x\n", msg
->MsgContext
);
372 mpt_print_init_reply(MSG_IOC_INIT_REPLY
*msg
)
375 mpt_print_reply_hdr((MSG_DEFAULT_REPLY
*)msg
);
376 kprintf("\tWhoInit %s\n", mpt_who(msg
->WhoInit
));
377 kprintf("\tMaxDevices 0x%02x\n", msg
->MaxDevices
);
378 kprintf("\tMaxBuses 0x%02x\n", msg
->MaxBuses
);
382 mpt_print_ioc_facts(MSG_IOC_FACTS_REPLY
*msg
)
385 mpt_print_reply_hdr((MSG_DEFAULT_REPLY
*)msg
);
386 kprintf("\tIOCNumber %d\n", msg
->IOCNumber
);
387 kprintf("\tMaxChainDepth %d\n", msg
->MaxChainDepth
);
388 kprintf("\tWhoInit %s\n", mpt_who(msg
->WhoInit
));
389 kprintf("\tBlockSize %d\n", msg
->BlockSize
);
390 kprintf("\tFlags %d\n", msg
->Flags
);
391 kprintf("\tReplyQueueDepth %d\n", msg
->ReplyQueueDepth
);
392 kprintf("\tReqFrameSize 0x%04x\n", msg
->RequestFrameSize
);
393 kprintf("\tFW Version 0x%08x\n", msg
->FWVersion
.Word
);
394 kprintf("\tProduct ID 0x%04x\n", msg
->ProductID
);
395 kprintf("\tCredits 0x%04x\n", msg
->GlobalCredits
);
396 kprintf("\tPorts %d\n", msg
->NumberOfPorts
);
397 kprintf("\tEventState 0x%02x\n", msg
->EventState
);
398 kprintf("\tHostMFA_HA 0x%08x\n", msg
->CurrentHostMfaHighAddr
);
399 kprintf("\tSenseBuf_HA 0x%08x\n",
400 msg
->CurrentSenseBufferHighAddr
);
401 kprintf("\tRepFrameSize 0x%04x\n", msg
->CurReplyFrameSize
);
402 kprintf("\tMaxDevices 0x%02x\n", msg
->MaxDevices
);
403 kprintf("\tMaxBuses 0x%02x\n", msg
->MaxBuses
);
404 kprintf("\tFWImageSize 0x%04x\n", msg
->FWImageSize
);
408 mpt_print_enable_reply(MSG_PORT_ENABLE_REPLY
*msg
)
411 mpt_print_reply_hdr((MSG_DEFAULT_REPLY
*)msg
);
412 kprintf("\tPort: %d\n", msg
->PortNumber
);
416 mpt_print_scsi_io_reply(MSG_SCSI_IO_REPLY
*msg
)
419 mpt_print_reply_hdr((MSG_DEFAULT_REPLY
*)msg
);
420 kprintf("\tBus: %d\n", msg
->Bus
);
421 kprintf("\tTargetID %d\n", msg
->TargetID
);
422 kprintf("\tCDBLength %d\n", msg
->CDBLength
);
423 kprintf("\tSCSI Status: %s\n", mpt_scsi_status(msg
->SCSIStatus
));
424 kprintf("\tSCSI State: %s\n", mpt_scsi_state(msg
->SCSIState
));
425 kprintf("\tTransferCnt 0x%04x\n", msg
->TransferCount
);
426 kprintf("\tSenseCnt 0x%04x\n", msg
->SenseCount
);
427 kprintf("\tResponseInfo 0x%08x\n", msg
->ResponseInfo
);
431 mpt_print_event_notice(MSG_EVENT_NOTIFY_REPLY
*msg
)
434 mpt_print_reply_hdr((MSG_DEFAULT_REPLY
*)msg
);
435 kprintf("\tEvent: %s\n", mpt_ioc_event(msg
->Event
));
436 kprintf("\tEventContext 0x%04x\n", msg
->EventContext
);
437 kprintf("\tAckRequired %d\n", msg
->AckRequired
);
438 kprintf("\tEventDataLength %d\n", msg
->EventDataLength
);
439 kprintf("\tContinuation %d\n", msg
->MsgFlags
& 0x80);
441 case MPI_EVENT_LOG_DATA
:
442 kprintf("\tEvtLogData: 0x%04x\n", msg
->Data
[0]);
445 case MPI_EVENT_UNIT_ATTENTION
:
446 kprintf("\tTargetID: 0x%04x\n",
447 msg
->Data
[0] & 0xff);
448 kprintf("\tBus: 0x%04x\n",
449 (msg
->Data
[0] >> 8) & 0xff);
452 case MPI_EVENT_IOC_BUS_RESET
:
453 case MPI_EVENT_EXT_BUS_RESET
:
454 case MPI_EVENT_RESCAN
:
455 kprintf("\tPort: %d\n",
456 (msg
->Data
[0] >> 8) & 0xff);
459 case MPI_EVENT_LINK_STATUS_CHANGE
:
460 kprintf("\tLinkState: %d\n",
461 msg
->Data
[0] & 0xff);
462 kprintf("\tPort: %d\n",
463 (msg
->Data
[1] >> 8) & 0xff);
466 case MPI_EVENT_LOOP_STATE_CHANGE
:
467 kprintf("\tType: %d\n",
468 (msg
->Data
[0] >> 16) & 0xff);
469 kprintf("\tChar3: 0x%02x\n",
470 (msg
->Data
[0] >> 8) & 0xff);
471 kprintf("\tChar4: 0x%02x\n",
472 (msg
->Data
[0] ) & 0xff);
473 kprintf("\tPort: %d\n",
474 (msg
->Data
[1] >> 8) & 0xff);
477 case MPI_EVENT_LOGOUT
:
478 kprintf("\tN_PortId: 0x%04x\n", msg
->Data
[0]);
479 kprintf("\tPort: %d\n",
480 (msg
->Data
[1] >> 8) & 0xff);
487 mpt_print_reply(void *vmsg
)
489 MSG_DEFAULT_REPLY
*msg
= vmsg
;
491 switch (msg
->Function
) {
492 case MPI_FUNCTION_EVENT_NOTIFICATION
:
493 mpt_print_event_notice((MSG_EVENT_NOTIFY_REPLY
*)msg
);
495 case MPI_FUNCTION_PORT_ENABLE
:
496 mpt_print_enable_reply((MSG_PORT_ENABLE_REPLY
*)msg
);
498 case MPI_FUNCTION_IOC_FACTS
:
499 mpt_print_ioc_facts((MSG_IOC_FACTS_REPLY
*)msg
);
501 case MPI_FUNCTION_IOC_INIT
:
502 mpt_print_init_reply((MSG_IOC_INIT_REPLY
*)msg
);
504 case MPI_FUNCTION_SCSI_IO_REQUEST
:
505 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
:
506 mpt_print_scsi_io_reply((MSG_SCSI_IO_REPLY
*)msg
);
509 mpt_print_reply_hdr(msg
);
514 /*****************************************************************************/
515 /* Request functions */
516 /*****************************************************************************/
518 mpt_print_request_hdr(MSG_REQUEST_HEADER
*req
)
520 kprintf("%s @ %p\n", mpt_ioc_function(req
->Function
), req
);
521 kprintf("\tChain Offset 0x%02x\n", req
->ChainOffset
);
522 kprintf("\tMsgFlags 0x%02x\n", req
->MsgFlags
);
523 kprintf("\tMsgContext 0x%08x\n", req
->MsgContext
);
527 mpt_print_scsi_io_request(MSG_SCSI_IO_REQUEST
*orig_msg
)
529 MSG_SCSI_IO_REQUEST local
, *msg
= &local
;
532 bcopy(orig_msg
, msg
, sizeof (MSG_SCSI_IO_REQUEST
));
533 mpt_print_request_hdr((MSG_REQUEST_HEADER
*)msg
);
534 kprintf("\tBus: %d\n", msg
->Bus
);
535 kprintf("\tTargetID %d\n", msg
->TargetID
);
536 kprintf("\tSenseBufferLength %d\n", msg
->SenseBufferLength
);
537 kprintf("\tLUN: 0x%0x\n", msg
->LUN
[1]);
538 kprintf("\tControl 0x%08x ", msg
->Control
);
539 #define MPI_PRINT_FIELD(x) \
540 case MPI_SCSIIO_CONTROL_ ## x : \
541 kprintf(" " #x " "); \
544 switch (msg
->Control
& MPI_SCSIIO_CONTROL_DATADIRECTION_MASK
) {
545 MPI_PRINT_FIELD(NODATATRANSFER
);
546 MPI_PRINT_FIELD(WRITE
);
547 MPI_PRINT_FIELD(READ
);
549 kprintf(" Invalid DIR! ");
552 switch (msg
->Control
& MPI_SCSIIO_CONTROL_TASKATTRIBUTE_MASK
) {
553 MPI_PRINT_FIELD(SIMPLEQ
);
554 MPI_PRINT_FIELD(HEADOFQ
);
555 MPI_PRINT_FIELD(ORDEREDQ
);
556 MPI_PRINT_FIELD(ACAQ
);
557 MPI_PRINT_FIELD(UNTAGGED
);
558 MPI_PRINT_FIELD(NO_DISCONNECT
);
560 kprintf(" Unknown attribute! ");
565 #undef MPI_PRINT_FIELD
567 kprintf("\tDataLength\t0x%08x\n", msg
->DataLength
);
568 kprintf("\tSenseBufAddr\t0x%08x\n", msg
->SenseBufferLowAddr
);
569 kprintf("\tCDB[0:%d]\t", msg
->CDBLength
);
570 for (i
= 0; i
< msg
->CDBLength
; i
++)
571 kprintf("%02x ", msg
->CDB
[i
]);
574 if ((msg
->Control
& MPI_SCSIIO_CONTROL_DATADIRECTION_MASK
) !=
575 MPI_SCSIIO_CONTROL_NODATATRANSFER
) {
576 mpt_dump_sgl(&orig_msg
->SGL
,
577 ((char *)&orig_msg
->SGL
)-(char *)orig_msg
);
582 mpt_print_scsi_tmf_request(MSG_SCSI_TASK_MGMT
*msg
)
585 mpt_print_request_hdr((MSG_REQUEST_HEADER
*)msg
);
586 kprintf("\tLun 0x%02x\n", msg
->LUN
[1]);
587 kprintf("\tTaskType %s\n", mpt_scsi_tm_type(msg
->TaskType
));
588 kprintf("\tTaskMsgContext 0x%08x\n", msg
->TaskMsgContext
);
593 mpt_print_scsi_target_assist_request(PTR_MSG_TARGET_ASSIST_REQUEST msg
)
596 mpt_print_request_hdr((MSG_REQUEST_HEADER
*)msg
);
597 kprintf("\tStatusCode 0x%02x\n", msg
->StatusCode
);
598 kprintf("\tTargetAssist 0x%02x\n", msg
->TargetAssistFlags
);
599 kprintf("\tQueueTag 0x%04x\n", msg
->QueueTag
);
600 kprintf("\tReplyWord 0x%08x\n", msg
->ReplyWord
);
601 kprintf("\tLun 0x%02x\n", msg
->LUN
[1]);
602 kprintf("\tRelativeOff 0x%08x\n", msg
->RelativeOffset
);
603 kprintf("\tDataLength 0x%08x\n", msg
->DataLength
);
604 mpt_dump_sgl(msg
->SGL
, 0);
608 mpt_print_scsi_target_status_send_request(MSG_TARGET_STATUS_SEND_REQUEST
*msg
)
612 mpt_print_request_hdr((MSG_REQUEST_HEADER
*)msg
);
613 kprintf("\tStatusCode 0x%02x\n", msg
->StatusCode
);
614 kprintf("\tStatusFlags 0x%02x\n", msg
->StatusFlags
);
615 kprintf("\tQueueTag 0x%04x\n", msg
->QueueTag
);
616 kprintf("\tReplyWord 0x%08x\n", msg
->ReplyWord
);
617 kprintf("\tLun 0x%02x\n", msg
->LUN
[1]);
618 x
.u
.Simple
= msg
->StatusDataSGE
;
623 mpt_print_request(void *vreq
)
625 MSG_REQUEST_HEADER
*req
= vreq
;
627 switch (req
->Function
) {
628 case MPI_FUNCTION_SCSI_IO_REQUEST
:
629 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
:
630 mpt_print_scsi_io_request((MSG_SCSI_IO_REQUEST
*)req
);
632 case MPI_FUNCTION_SCSI_TASK_MGMT
:
633 mpt_print_scsi_tmf_request((MSG_SCSI_TASK_MGMT
*)req
);
635 case MPI_FUNCTION_TARGET_ASSIST
:
636 mpt_print_scsi_target_assist_request(
637 (PTR_MSG_TARGET_ASSIST_REQUEST
)req
);
639 case MPI_FUNCTION_TARGET_STATUS_SEND
:
640 mpt_print_scsi_target_status_send_request(
641 (MSG_TARGET_STATUS_SEND_REQUEST
*)req
);
644 mpt_print_request_hdr(req
);
650 typedef struct mpt_decode_entry
{
654 } mpt_decode_entry_t
;
657 mpt_decode_value(mpt_decode_entry_t
*table
, u_int num_entries
,
658 const char *name
, u_int value
, u_int
*cur_column
,
665 if (cur_column
== NULL
) {
667 cur_column
= &dummy_column
;
670 if (*cur_column
>= wrap_point
) {
674 printed
= kprintf("%s[0x%x]", name
, value
);
676 printed
+= kprintf(" ");
677 *cur_column
+= printed
;
681 while (printed_mask
!= 0xFF) {
684 for (entry
= 0; entry
< num_entries
; entry
++) {
685 if (((value
& table
[entry
].mask
)
686 != table
[entry
].value
)
687 || ((printed_mask
& table
[entry
].mask
)
688 == table
[entry
].mask
))
691 printed
+= kprintf("%s%s",
692 printed_mask
== 0 ? ":(" : "|",
694 printed_mask
|= table
[entry
].mask
;
697 if (entry
>= num_entries
)
700 if (printed_mask
!= 0)
701 printed
+= kprintf(") ");
703 printed
+= kprintf(" ");
704 *cur_column
+= printed
;
708 static const mpt_decode_entry_t req_state_parse_table
[] = {
709 { "REQ_FREE", 0x00, 0xff },
710 { "REQ_ALLOCATED", 0x01, 0x01 },
711 { "REQ_QUEUED", 0x02, 0x02 },
712 { "REQ_DONE", 0x04, 0x04 },
713 { "REQ_TIMEDOUT", 0x08, 0x08 },
714 { "REQ_NEED_WAKEUP", 0x10, 0x10 }
718 mpt_req_state(mpt_req_state_t state
)
721 mpt_decode_value(req_state_parse_table
,
722 NUM_ELEMENTS(req_state_parse_table
),
723 "REQ_STATE", state
, NULL
, 80);
728 MPI_SGE_FLAGS_END_OF_LIST | \
729 MPI_SGE_FLAGS_END_OF_BUFFER| \
730 MPI_SGE_FLAGS_LAST_ELEMENT)
732 mpt_dump_sgl(SGE_IO_UNION
*su
, int offset
)
734 SGE_SIMPLE32
*se
= (SGE_SIMPLE32
*) su
;
735 const char allfox
[4] = { 0xff, 0xff, 0xff, 0xff };
741 * Can't be any bigger than this.
743 lim
= &((char *)se
)[MPT_REQUEST_AREA
- offset
];
749 if (memcmp(se
, allfox
, 4) == 0) {
750 uint32_t *nxt
= (uint32_t *)se
;
751 kprintf("PAD %p\n", se
);
758 flags
= MPI_SGE_GET_FLAGS(se
->FlagsLength
);
759 switch (flags
& MPI_SGE_FLAGS_ELEMENT_MASK
) {
760 case MPI_SGE_FLAGS_SIMPLE_ELEMENT
:
761 if (flags
& MPI_SGE_FLAGS_64_BIT_ADDRESSING
) {
762 SGE_SIMPLE64
*se64
= (SGE_SIMPLE64
*)se
;
763 kprintf("SE64 %p: Addr=0x%08x%08x FlagsLength"
764 "=0x%0x\n", se64
, se64
->Address
.High
,
765 se64
->Address
.Low
, se64
->FlagsLength
);
768 kprintf("SE32 %p: Addr=0x%0x FlagsLength=0x%0x"
769 "\n", se
, se
->Address
, se
->FlagsLength
);
773 case MPI_SGE_FLAGS_CHAIN_ELEMENT
:
774 if (flags
& MPI_SGE_FLAGS_64_BIT_ADDRESSING
) {
775 SGE_CHAIN64
*ce64
= (SGE_CHAIN64
*) se
;
776 kprintf("CE64 %p: Addr=0x%08x%08x NxtChnO=0x%x "
777 "Flgs=0x%x Len=0x%0x\n", ce64
,
778 ce64
->Address
.High
, ce64
->Address
.Low
,
779 ce64
->NextChainOffset
,
780 ce64
->Flags
, ce64
->Length
);
783 SGE_CHAIN32
*ce
= (SGE_CHAIN32
*) se
;
784 kprintf("CE32 %p: Addr=0x%0x NxtChnO=0x%x "
785 " Flgs=0x%x Len=0x%0x\n", ce
, ce
->Address
,
786 ce
->NextChainOffset
, ce
->Flags
, ce
->Length
);
790 case MPI_SGE_FLAGS_TRANSACTION_ELEMENT
:
791 kprintf("TE32 @ %p\n", se
);
796 #define MPT_PRINT_FLAG(x) \
797 if (flags & MPI_SGE_FLAGS_ ## x ) { \
805 MPT_PRINT_FLAG(LOCAL_ADDRESS
);
806 MPT_PRINT_FLAG(HOST_TO_IOC
);
807 MPT_PRINT_FLAG(64_BIT_ADDRESSING
);
808 MPT_PRINT_FLAG(LAST_ELEMENT
);
809 MPT_PRINT_FLAG(END_OF_BUFFER
);
810 MPT_PRINT_FLAG(END_OF_LIST
);
811 #undef MPT_PRINT_FLAG
815 if ((flags
& LAST_SGE
) == LAST_SGE
) {
818 } while ((flags
& MPI_SGE_FLAGS_END_OF_LIST
) == 0 && nxtaddr
< lim
);
822 mpt_dump_data(struct mpt_softc
*mpt
, const char *msg
, void *addr
, int len
)
827 mpt_prt(mpt
, "%s:", msg
);
828 for (offset
= 0; offset
< len
; offset
++) {
829 if ((offset
& 0xf) == 0) {
832 mpt_prtc(mpt
, " %02x", cp
[offset
]);
838 mpt_dump_request(struct mpt_softc
*mpt
, request_t
*req
)
840 uint32_t *pReq
= req
->req_vbuf
;
843 mpt_prt(mpt
, "Send Request %d (%jx):",
844 req
->index
, (uintmax_t) req
->req_pbuf
);
845 for (o
= 0; o
< mpt
->ioc_facts
.RequestFrameSize
; o
++) {
846 if ((o
& 0x7) == 0) {
850 mpt_prtc(mpt
, " %08x", pReq
[o
]);
856 mpt_prt(struct mpt_softc
*mpt
, const char *fmt
, ...)
860 kprintf("%s: ", device_get_nameunit(mpt
->dev
));
867 mpt_prtc(struct mpt_softc
*mpt
, const char *fmt
, ...)