xref: /dragonfly/sys/dev/raid/mpr/mpr_table.c (revision 37de577a)
1 /*-
2  * Copyright (c) 2009 Yahoo! Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: head/sys/dev/mpr/mpr_table.c 323380 2017-09-09 22:02:36Z scottl $
27  */
28 
29 /* Debugging tables for MPT2 */
30 
31 /* TODO Move headers to mprvar */
32 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/bus.h>
38 #include <sys/conf.h>
39 #include <sys/bio.h>
40 #include <sys/malloc.h>
41 #include <sys/uio.h>
42 #include <sys/sysctl.h>
43 #include <sys/queue.h>
44 #include <sys/kthread.h>
45 #include <sys/taskqueue.h>
46 #include <sys/eventhandler.h>
47 
48 #include <sys/rman.h>
49 
50 #include <bus/cam/scsi/scsi_all.h>
51 
52 #include <dev/raid/mpr/mpi/mpi2_type.h>
53 #include <dev/raid/mpr/mpi/mpi2.h>
54 #include <dev/raid/mpr/mpi/mpi2_ioc.h>
55 #include <dev/raid/mpr/mpi/mpi2_cnfg.h>
56 #include <dev/raid/mpr/mpi/mpi2_init.h>
57 #include <dev/raid/mpr/mpi/mpi2_tool.h>
58 #include <dev/raid/mpr/mpi/mpi2_pci.h>
59 #include <dev/raid/mpr/mpr_ioctl.h>
60 #include <dev/raid/mpr/mprvar.h>
61 #include <dev/raid/mpr/mpr_table.h>
62 
63 char *
64 mpr_describe_table(struct mpr_table_lookup *table, u_int code)
65 {
66 	int i;
67 
68 	for (i = 0; table[i].string != NULL; i++) {
69 		if (table[i].code == code)
70 			return(table[i].string);
71 	}
72 	return(table[i+1].string);
73 }
74 
75 //SLM-Add new PCIe info to all of these tables
76 struct mpr_table_lookup mpr_event_names[] = {
77 	{"LogData",			0x01},
78 	{"StateChange",			0x02},
79 	{"HardResetReceived",		0x05},
80 	{"EventChange",			0x0a},
81 	{"TaskSetFull",			0x0e},
82 	{"SasDeviceStatusChange",	0x0f},
83 	{"IrOperationStatus",		0x14},
84 	{"SasDiscovery",		0x16},
85 	{"SasBroadcastPrimitive",	0x17},
86 	{"SasInitDeviceStatusChange",	0x18},
87 	{"SasInitTableOverflow",	0x19},
88 	{"SasTopologyChangeList",	0x1c},
89 	{"SasEnclDeviceStatusChange",	0x1d},
90 	{"IrVolume",			0x1e},
91 	{"IrPhysicalDisk",		0x1f},
92 	{"IrConfigurationChangeList",	0x20},
93 	{"LogEntryAdded",		0x21},
94 	{"SasPhyCounter",		0x22},
95 	{"GpioInterrupt",		0x23},
96 	{"HbdPhyEvent",			0x24},
97 	{"SasQuiesce",			0x25},
98 	{"SasNotifyPrimitive",		0x26},
99 	{"TempThreshold",		0x27},
100 	{"HostMessage",			0x28},
101 	{"PowerPerformanceChange",	0x29},
102 	{"PCIeDeviceStatusChange",	0x30},
103 	{"PCIeEnumeration",		0x31},
104 	{"PCIeTopologyChangeList",	0x32},
105 	{"PCIeLinkCounter",		0x33},
106 	{"CableEvent",			0x34},
107 	{NULL, 0},
108 	{"Unknown Event", 0}
109 };
110 
111 struct mpr_table_lookup mpr_phystatus_names[] = {
112 	{"NewTargetAdded",		0x01},
113 	{"TargetGone",			0x02},
114 	{"PHYLinkStatusChange",		0x03},
115 	{"PHYLinkStatusUnchanged",	0x04},
116 	{"TargetMissing",		0x05},
117 	{NULL, 0},
118 	{"Unknown Status", 0}
119 };
120 
121 struct mpr_table_lookup mpr_linkrate_names[] = {
122 	{"PHY disabled",		0x01},
123 	{"Speed Negotiation Failed",	0x02},
124 	{"SATA OOB Complete",		0x03},
125 	{"SATA Port Selector",		0x04},
126 	{"SMP Reset in Progress",	0x05},
127 	{"1.5Gbps",			0x08},
128 	{"3.0Gbps",			0x09},
129 	{"6.0Gbps",			0x0a},
130 	{"12.0Gbps",			0x0b},
131 	{NULL, 0},
132 	{"LinkRate Unknown",		0x00}
133 };
134 
135 struct mpr_table_lookup mpr_sasdev0_devtype[] = {
136 	{"End Device",			0x01},
137 	{"Edge Expander",		0x02},
138 	{"Fanout Expander",		0x03},
139 	{NULL, 0},
140 	{"No Device",			0x00}
141 };
142 
143 struct mpr_table_lookup mpr_phyinfo_reason_names[] = {
144 	{"Power On",			0x01},
145 	{"Hard Reset",			0x02},
146 	{"SMP Phy Control Link Reset",	0x03},
147 	{"Loss DWORD Sync",		0x04},
148 	{"Multiplex Sequence",		0x05},
149 	{"I-T Nexus Loss Timer",	0x06},
150 	{"Break Timeout Timer",		0x07},
151 	{"PHY Test Function",		0x08},
152 	{NULL, 0},
153 	{"Unknown Reason",		0x00}
154 };
155 
156 struct mpr_table_lookup mpr_whoinit_names[] = {
157 	{"System BIOS",			0x01},
158 	{"ROM BIOS",			0x02},
159 	{"PCI Peer",			0x03},
160 	{"Host Driver",			0x04},
161 	{"Manufacturing",		0x05},
162 	{NULL, 0},
163 	{"Not Initialized",		0x00}
164 };
165 
166 struct mpr_table_lookup mpr_sasdisc_reason[] = {
167 	{"Discovery Started",		0x01},
168 	{"Discovery Complete",		0x02},
169 	{NULL, 0},
170 	{"Unknown",			0x00}
171 };
172 
173 struct mpr_table_lookup mpr_sastopo_exp[] = {
174 	{"Added",			0x01},
175 	{"Not Responding",		0x02},
176 	{"Responding",			0x03},
177 	{"Delay Not Responding",	0x04},
178 	{NULL, 0},
179 	{"Unknown",			0x00}
180 };
181 
182 struct mpr_table_lookup mpr_sasdev_reason[] = {
183 	{"SMART Data",			0x05},
184 	{"Unsupported",			0x07},
185 	{"Internal Device Reset",	0x08},
186 	{"Task Abort Internal",		0x09},
187 	{"Abort Task Set Internal",	0x0a},
188 	{"Clear Task Set Internal",	0x0b},
189 	{"Query Task Internal",		0x0c},
190 	{"Async Notification",		0x0d},
191 	{"Cmp Internal Device Reset",	0x0e},
192 	{"Cmp Task Abort Internal",	0x0f},
193 	{"Sata Init Failure",		0x10},
194 	{NULL, 0},
195 	{"Unknown",			0x00}
196 };
197 
198 struct mpr_table_lookup mpr_pcie_linkrate_names[] = {
199 	{"Port disabled",		0x01},
200 	{"2.5GT/sec",			0x02},
201 	{"5.0GT/sec",			0x03},
202 	{"8.0GT/sec",			0x04},
203 	{"16.0GT/sec",			0x05},
204 	{NULL, 0},
205 	{"LinkRate Unknown",		0x00}
206 };
207 
208 struct mpr_table_lookup mpr_iocstatus_string[] = {
209 	{"success",			MPI2_IOCSTATUS_SUCCESS},
210 	{"invalid function",		MPI2_IOCSTATUS_INVALID_FUNCTION},
211 	{"scsi recovered error",	MPI2_IOCSTATUS_SCSI_RECOVERED_ERROR},
212 	{"scsi invalid dev handle",	MPI2_IOCSTATUS_SCSI_INVALID_DEVHANDLE},
213 	{"scsi device not there",	MPI2_IOCSTATUS_SCSI_DEVICE_NOT_THERE},
214 	{"scsi data overrun",		MPI2_IOCSTATUS_SCSI_DATA_OVERRUN},
215 	{"scsi data underrun",		MPI2_IOCSTATUS_SCSI_DATA_UNDERRUN},
216 	{"scsi io data error",		MPI2_IOCSTATUS_SCSI_IO_DATA_ERROR},
217 	{"scsi protocol error",		MPI2_IOCSTATUS_SCSI_PROTOCOL_ERROR},
218 	{"scsi task terminated",	MPI2_IOCSTATUS_SCSI_TASK_TERMINATED},
219 	{"scsi residual mismatch",	MPI2_IOCSTATUS_SCSI_RESIDUAL_MISMATCH},
220 	{"scsi task mgmt failed",	MPI2_IOCSTATUS_SCSI_TASK_MGMT_FAILED},
221 	{"scsi ioc terminated",		MPI2_IOCSTATUS_SCSI_IOC_TERMINATED},
222 	{"scsi ext terminated",		MPI2_IOCSTATUS_SCSI_EXT_TERMINATED},
223 	{"eedp guard error",		MPI2_IOCSTATUS_EEDP_GUARD_ERROR},
224 	{"eedp ref tag error",		MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR},
225 	{"eedp app tag error",		MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR},
226 	{NULL, 0},
227 	{"unknown",			0x00}
228 };
229 
230 struct mpr_table_lookup mpr_scsi_status_string[] = {
231 	{"good",			MPI2_SCSI_STATUS_GOOD},
232 	{"check condition",		MPI2_SCSI_STATUS_CHECK_CONDITION},
233 	{"condition met",		MPI2_SCSI_STATUS_CONDITION_MET},
234 	{"busy",			MPI2_SCSI_STATUS_BUSY},
235 	{"intermediate",		MPI2_SCSI_STATUS_INTERMEDIATE},
236 	{"intermediate condmet",	MPI2_SCSI_STATUS_INTERMEDIATE_CONDMET},
237 	{"reservation conflict",	MPI2_SCSI_STATUS_RESERVATION_CONFLICT},
238 	{"command terminated",		MPI2_SCSI_STATUS_COMMAND_TERMINATED},
239 	{"task set full",		MPI2_SCSI_STATUS_TASK_SET_FULL},
240 	{"aca active",			MPI2_SCSI_STATUS_ACA_ACTIVE},
241 	{"task aborted",		MPI2_SCSI_STATUS_TASK_ABORTED},
242 	{NULL, 0},
243 	{"unknown",			0x00}
244 };
245 
246 struct mpr_table_lookup mpr_scsi_taskmgmt_string[] = {
247 	{"task mgmt request completed",	MPI2_SCSITASKMGMT_RSP_TM_COMPLETE},
248 	{"invalid frame",		MPI2_SCSITASKMGMT_RSP_INVALID_FRAME},
249 	{"task mgmt request not supp",	MPI2_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED},
250 	{"task mgmt request failed",	MPI2_SCSITASKMGMT_RSP_TM_FAILED},
251 	{"task mgmt request_succeeded",	MPI2_SCSITASKMGMT_RSP_TM_SUCCEEDED},
252 	{"invalid lun",			MPI2_SCSITASKMGMT_RSP_TM_INVALID_LUN},
253 	{"overlapped tag attempt",	0xA},
254 	{"task queued on IOC",		MPI2_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC},
255 	{NULL, 0},
256 	{"unknown",			0x00}
257 };
258 
259 void
260 mpr_describe_devinfo(uint32_t devinfo, char *string, int len)
261 {
262 	ksnprintf(string, len, "%pb%i,%s",
263 	    "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
264 	    "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
265 	    "\15LsiDev" "\16AtapiDev" "\17SepDev",
266 	    devinfo,
267 	    mpr_describe_table(mpr_sasdev0_devtype, devinfo & 0x03));
268 }
269 
270 void
271 mpr_print_iocfacts(struct mpr_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
272 {
273 	MPR_PRINTFIELD_START(sc, "IOCFacts");
274 	MPR_PRINTFIELD(sc, facts, MsgVersion, 0x%x);
275 	MPR_PRINTFIELD(sc, facts, HeaderVersion, 0x%x);
276 	MPR_PRINTFIELD(sc, facts, IOCNumber, %d);
277 	MPR_PRINTFIELD(sc, facts, IOCExceptions, 0x%x);
278 	MPR_PRINTFIELD(sc, facts, MaxChainDepth, %d);
279 	mpr_print_field(sc, "WhoInit: %s\n",
280 	    mpr_describe_table(mpr_whoinit_names, facts->WhoInit));
281 	MPR_PRINTFIELD(sc, facts, NumberOfPorts, %d);
282 	MPR_PRINTFIELD(sc, facts, MaxMSIxVectors, %d);
283 	MPR_PRINTFIELD(sc, facts, RequestCredit, %d);
284 	MPR_PRINTFIELD(sc, facts, ProductID, 0x%x);
285 	mpr_print_field(sc, "IOCCapabilities: %pb%i\n",
286 	    "\20" "\3ScsiTaskFull" "\4DiagTrace"
287 	    "\5SnapBuf" "\6ExtBuf" "\7EEDP" "\10BiDirTarg" "\11Multicast"
288 	    "\14TransRetry" "\15IR" "\16EventReplay" "\17RaidAccel"
289 	    "\20MSIXIndex" "\21HostDisc",
290 	    facts->IOCCapabilities);
291 	mpr_print_field(sc, "FWVersion= %d-%d-%d-%d\n",
292 	    facts->FWVersion.Struct.Major,
293 	    facts->FWVersion.Struct.Minor,
294 	    facts->FWVersion.Struct.Unit,
295 	    facts->FWVersion.Struct.Dev);
296 	MPR_PRINTFIELD(sc, facts, IOCRequestFrameSize, %d);
297 	MPR_PRINTFIELD(sc, facts, MaxInitiators, %d);
298 	MPR_PRINTFIELD(sc, facts, MaxTargets, %d);
299 	MPR_PRINTFIELD(sc, facts, MaxSasExpanders, %d);
300 	MPR_PRINTFIELD(sc, facts, MaxEnclosures, %d);
301 	mpr_print_field(sc, "ProtocolFlags: %pb%i\n",
302 	    "\20" "\1ScsiTarg" "\2ScsiInit",
303 	    facts->ProtocolFlags);
304 	MPR_PRINTFIELD(sc, facts, HighPriorityCredit, %d);
305 	MPR_PRINTFIELD(sc, facts, MaxReplyDescriptorPostQueueDepth, %d);
306 	MPR_PRINTFIELD(sc, facts, ReplyFrameSize, %d);
307 	MPR_PRINTFIELD(sc, facts, MaxVolumes, %d);
308 	MPR_PRINTFIELD(sc, facts, MaxDevHandle, %d);
309 	MPR_PRINTFIELD(sc, facts, MaxPersistentEntries, %d);
310 }
311 
312 void
313 mpr_print_portfacts(struct mpr_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
314 {
315 
316 	MPR_PRINTFIELD_START(sc, "PortFacts");
317 	MPR_PRINTFIELD(sc, facts, PortNumber, %d);
318 	MPR_PRINTFIELD(sc, facts, PortType, 0x%x);
319 	MPR_PRINTFIELD(sc, facts, MaxPostedCmdBuffers, %d);
320 }
321 
322 void
323 mpr_print_evt_generic(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
324 {
325 
326 	MPR_PRINTFIELD_START(sc, "EventReply");
327 	MPR_PRINTFIELD(sc, event, EventDataLength, %d);
328 	MPR_PRINTFIELD(sc, event, AckRequired, %d);
329 	mpr_print_field(sc, "Event: %s (0x%x)\n",
330 	    mpr_describe_table(mpr_event_names, event->Event), event->Event);
331 	MPR_PRINTFIELD(sc, event, EventContext, 0x%x);
332 }
333 
334 void
335 mpr_print_sasdev0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
336 {
337 	MPR_PRINTFIELD_START(sc, "SAS Device Page 0");
338 	MPR_PRINTFIELD(sc, buf, Slot, %d);
339 	MPR_PRINTFIELD(sc, buf, EnclosureHandle, 0x%x);
340 	mpr_print_field(sc, "SASAddress: 0x%jx\n",
341 	    mpr_to_u64(&buf->SASAddress));
342 	MPR_PRINTFIELD(sc, buf, ParentDevHandle, 0x%x);
343 	MPR_PRINTFIELD(sc, buf, PhyNum, %d);
344 	MPR_PRINTFIELD(sc, buf, AccessStatus, 0x%x);
345 	MPR_PRINTFIELD(sc, buf, DevHandle, 0x%x);
346 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, 0x%x);
347 	MPR_PRINTFIELD(sc, buf, ZoneGroup, %d);
348 	mpr_print_field(sc, "DeviceInfo: %pb%i,%s\n",
349 	    "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
350 	    "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
351 	    "\15LsiDev" "\16AtapiDev" "\17SepDev",
352 	    buf->DeviceInfo,
353 	    mpr_describe_table(mpr_sasdev0_devtype, buf->DeviceInfo & 0x03));
354 	MPR_PRINTFIELD(sc, buf, Flags, 0x%x);
355 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
356 	MPR_PRINTFIELD(sc, buf, MaxPortConnections, %d);
357 	mpr_print_field(sc, "DeviceName: 0x%jx\n",
358 	    mpr_to_u64(&buf->DeviceName));
359 	MPR_PRINTFIELD(sc, buf, PortGroups, %d);
360 	MPR_PRINTFIELD(sc, buf, DmaGroup, %d);
361 	MPR_PRINTFIELD(sc, buf, ControlGroup, %d);
362 }
363 
364 void
365 mpr_print_evt_sas(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
366 {
367 
368 	mpr_print_evt_generic(sc, event);
369 
370 	switch(event->Event) {
371 	case MPI2_EVENT_SAS_DISCOVERY:
372 	{
373 		MPI2_EVENT_DATA_SAS_DISCOVERY *data;
374 
375 		data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
376 		mpr_print_field(sc, "Flags: %pb%i\n",
377 		    "\20" "\1InProgress" "\2DeviceChange",
378 		    data->Flags);
379 		mpr_print_field(sc, "ReasonCode: %s\n",
380 		    mpr_describe_table(mpr_sasdisc_reason, data->ReasonCode));
381 		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
382 		mpr_print_field(sc, "DiscoveryStatus: %pb%i\n",
383 		    "\20"
384 		    "\1Loop" "\2UnaddressableDev" "\3DupSasAddr" "\5SmpTimeout"
385 		    "\6ExpRouteFull" "\7RouteIndexError" "\10SmpFailed"
386 		    "\11SmpCrcError" "\12SubSubLink" "\13TableTableLink"
387 		    "\14UnsupDevice" "\15TableSubLink" "\16MultiDomain"
388 		    "\17MultiSub" "\20MultiSubSub" "\34DownstreamInit"
389 		    "\35MaxPhys" "\36MaxTargs" "\37MaxExpanders"
390 		    "\40MaxEnclosures",
391 		    data->DiscoveryStatus);
392 		break;
393 	}
394 //SLM-add for PCIE EVENT too
395 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
396 	{
397 		MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
398 		MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
399 		int i, phynum;
400 
401 		data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
402 		    &event->EventData;
403 		MPR_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
404 		MPR_PRINTFIELD(sc, data, ExpanderDevHandle, 0x%x);
405 		MPR_PRINTFIELD(sc, data, NumPhys, %d);
406 		MPR_PRINTFIELD(sc, data, NumEntries, %d);
407 		MPR_PRINTFIELD(sc, data, StartPhyNum, %d);
408 		mpr_print_field(sc, "ExpStatus: %s (0x%x)\n",
409 		    mpr_describe_table(mpr_sastopo_exp, data->ExpStatus),
410 		    data->ExpStatus);
411 		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
412 		for (i = 0; i < data->NumEntries; i++) {
413 			phy = &data->PHY[i];
414 			phynum = data->StartPhyNum + i;
415 			mpr_print_field(sc,
416 			    "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
417 			    phy->AttachedDevHandle);
418 			mpr_print_field(sc,
419 			    "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
420 			    mpr_describe_table(mpr_linkrate_names,
421 			    (phy->LinkRate >> 4) & 0xf), phy->LinkRate);
422 			mpr_print_field(sc, "PHY[%d].PhyStatus: %s\n",
423 			    phynum, mpr_describe_table(mpr_phystatus_names,
424 			    phy->PhyStatus));
425 		}
426 		break;
427 	}
428 	case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
429 	{
430 		MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *data;
431 
432 		data = (MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *)
433 		    &event->EventData;
434 		MPR_PRINTFIELD(sc, data, EnclosureHandle, 0x%x);
435 		mpr_print_field(sc, "ReasonCode: %s\n",
436 		    mpr_describe_table(mpr_sastopo_exp, data->ReasonCode));
437 		MPR_PRINTFIELD(sc, data, PhysicalPort, %d);
438 		MPR_PRINTFIELD(sc, data, NumSlots, %d);
439 		MPR_PRINTFIELD(sc, data, StartSlot, %d);
440 		MPR_PRINTFIELD(sc, data, PhyBits, 0x%x);
441 		break;
442 	}
443 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
444 	{
445 		MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *data;
446 
447 		data = (MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
448 		    &event->EventData;
449 		MPR_PRINTFIELD(sc, data, TaskTag, 0x%x);
450 		mpr_print_field(sc, "ReasonCode: %s\n",
451 		    mpr_describe_table(mpr_sasdev_reason, data->ReasonCode));
452 		MPR_PRINTFIELD(sc, data, ASC, 0x%x);
453 		MPR_PRINTFIELD(sc, data, ASCQ, 0x%x);
454 		MPR_PRINTFIELD(sc, data, DevHandle, 0x%x);
455 		mpr_print_field(sc, "SASAddress: 0x%jx\n",
456 		    mpr_to_u64(&data->SASAddress));
457 	}
458 	default:
459 		break;
460 	}
461 }
462 
463 void
464 mpr_print_expander1(struct mpr_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
465 {
466 	MPR_PRINTFIELD_START(sc, "SAS Expander Page 1 #%d", buf->Phy);
467 	MPR_PRINTFIELD(sc, buf, PhysicalPort, %d);
468 	MPR_PRINTFIELD(sc, buf, NumPhys, %d);
469 	MPR_PRINTFIELD(sc, buf, Phy, %d);
470 	MPR_PRINTFIELD(sc, buf, NumTableEntriesProgrammed, %d);
471 	mpr_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
472 	    mpr_describe_table(mpr_linkrate_names,
473 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
474 	mpr_print_field(sc, "HwLinkRate: %s (0x%x)\n",
475 	    mpr_describe_table(mpr_linkrate_names,
476 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
477 	MPR_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
478 	mpr_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
479 	    mpr_describe_table(mpr_phyinfo_reason_names,
480 	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
481 	mpr_print_field(sc, "AttachedDeviceInfo: %pb%i,%s\n",
482 	    "\20" "\4SATAhost" "\5SMPinit" "\6STPinit"
483 	    "\7SSPinit" "\10SATAdev" "\11SMPtarg" "\12STPtarg" "\13SSPtarg"
484 	    "\14Direct" "\15LSIdev" "\16ATAPIdev" "\17SEPdev",
485 	    buf->AttachedDeviceInfo,
486 	    mpr_describe_table(mpr_sasdev0_devtype,
487 	    buf->AttachedDeviceInfo & 0x03));
488 	MPR_PRINTFIELD(sc, buf, ExpanderDevHandle, 0x%04x);
489 	MPR_PRINTFIELD(sc, buf, ChangeCount, %d);
490 	mpr_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
491 	    mpr_describe_table(mpr_linkrate_names,
492 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
493 	MPR_PRINTFIELD(sc, buf, PhyIdentifier, %d);
494 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
495 	MPR_PRINTFIELD(sc, buf, DiscoveryInfo, 0x%x);
496 	MPR_PRINTFIELD(sc, buf, AttachedPhyInfo, 0x%x);
497 	mpr_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
498 	    mpr_describe_table(mpr_phyinfo_reason_names,
499 	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
500 	MPR_PRINTFIELD(sc, buf, ZoneGroup, %d);
501 	MPR_PRINTFIELD(sc, buf, SelfConfigStatus, 0x%x);
502 }
503 
504 void
505 mpr_print_sasphy0(struct mpr_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
506 {
507 	MPR_PRINTFIELD_START(sc, "SAS PHY Page 0");
508 	MPR_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);
509 	MPR_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
510 	MPR_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
511 	mpr_print_field(sc, "AttachedPhyInfo Reason: %s (0x%x)\n",
512 	    mpr_describe_table(mpr_phyinfo_reason_names,
513 	    buf->AttachedPhyInfo & 0xf), buf->AttachedPhyInfo);
514 	mpr_print_field(sc, "ProgrammedLinkRate: %s (0x%x)\n",
515 	    mpr_describe_table(mpr_linkrate_names,
516 	    (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
517 	mpr_print_field(sc, "HwLinkRate: %s (0x%x)\n",
518 	    mpr_describe_table(mpr_linkrate_names,
519 	    (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
520 	MPR_PRINTFIELD(sc, buf, ChangeCount, %d);
521 	MPR_PRINTFIELD(sc, buf, Flags, 0x%x);
522 	mpr_print_field(sc, "PhyInfo Reason: %s (0x%x)\n",
523 	    mpr_describe_table(mpr_phyinfo_reason_names,
524 	    (buf->PhyInfo >> 16) & 0xf), buf->PhyInfo);
525 	mpr_print_field(sc, "NegotiatedLinkRate: %s (0x%x)\n",
526 	    mpr_describe_table(mpr_linkrate_names,
527 	    buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
528 }
529 
530 void
531 mpr_print_sgl(struct mpr_softc *sc, struct mpr_command *cm, int offset)
532 {
533 	MPI2_IEEE_SGE_SIMPLE64 *ieee_sge;
534 	MPI25_IEEE_SGE_CHAIN64 *ieee_sgc;
535 	MPI2_SGE_SIMPLE64 *sge;
536 	MPI2_REQUEST_HEADER *req;
537 	struct mpr_chain *chain = NULL;
538 	char *frame;
539 	u_int i = 0, flags, length;
540 
541 	req = (MPI2_REQUEST_HEADER *)cm->cm_req;
542 	frame = (char *)cm->cm_req;
543 	ieee_sge = (MPI2_IEEE_SGE_SIMPLE64 *)&frame[offset * 4];
544 	sge = (MPI2_SGE_SIMPLE64 *)&frame[offset * 4];
545 	kprintf("SGL for command %p\n", cm);
546 
547 	hexdump(frame, 128, NULL, 0);
548 	while ((frame != NULL) && (!(cm->cm_flags & MPR_CM_FLAGS_SGE_SIMPLE))) {
549 		flags = ieee_sge->Flags;
550 		length = le32toh(ieee_sge->Length);
551 		kprintf("IEEE seg%d flags=0x%02x len=0x%08x addr=0x%016jx\n", i,
552 		    flags, length, mpr_to_u64(&ieee_sge->Address));
553 		if (flags & MPI25_IEEE_SGE_FLAGS_END_OF_LIST)
554 			break;
555 		ieee_sge++;
556 		i++;
557 		if (flags & MPI2_IEEE_SGE_FLAGS_CHAIN_ELEMENT) {
558 			ieee_sgc = (MPI25_IEEE_SGE_CHAIN64 *)ieee_sge;
559 			kprintf("IEEE chain flags=0x%x len=0x%x Offset=0x%x "
560 			    "Address=0x%016jx\n", ieee_sgc->Flags,
561 			    le32toh(ieee_sgc->Length),
562 			    ieee_sgc->NextChainOffset,
563 			    mpr_to_u64(&ieee_sgc->Address));
564 			if (chain == NULL)
565 				chain = TAILQ_FIRST(&cm->cm_chain_list);
566 			else
567 				chain = TAILQ_NEXT(chain, chain_link);
568 			frame = (char *)chain->chain;
569 			ieee_sge = (MPI2_IEEE_SGE_SIMPLE64 *)frame;
570 			hexdump(frame, 128, NULL, 0);
571 		}
572 	}
573 	while ((frame != NULL) && (cm->cm_flags & MPR_CM_FLAGS_SGE_SIMPLE)) {
574 		flags = le32toh(sge->FlagsLength) >> MPI2_SGE_FLAGS_SHIFT;
575 		kprintf("seg%d flags=0x%02x len=0x%06x addr=0x%016jx\n", i,
576 		    flags, le32toh(sge->FlagsLength) & 0xffffff,
577 		    mpr_to_u64(&sge->Address));
578 		if (flags & (MPI2_SGE_FLAGS_END_OF_LIST |
579 		    MPI2_SGE_FLAGS_END_OF_BUFFER))
580 			break;
581 		sge++;
582 		i++;
583 	}
584 }
585 
586 void
587 mpr_print_scsiio_cmd(struct mpr_softc *sc, struct mpr_command *cm)
588 {
589 	MPI2_SCSI_IO_REQUEST *req;
590 
591 	req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
592 	mpr_print_sgl(sc, cm, req->SGLOffset0);
593 }
594 
595