Bring in mps(4) for LSI Fusion-MPT 2 Serial Attached SCSI controllers.
[dragonfly.git] / sys / dev / disk / mps / mps_table.c
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: src/sys/dev/mps/mps_table.c,v 1.1 2010/09/10 15:03:56 ken Exp $
27  */
28
29 /* Debugging tables for MPT2 */
30
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/bus.h>
37 #include <sys/conf.h>
38 #include <sys/bio.h>
39 #include <sys/malloc.h>
40 #include <sys/uio.h>
41 #include <sys/sysctl.h>
42
43 #include <sys/rman.h>
44 #include <sys/lock.h>
45
46 #include <bus/cam/scsi/scsi_all.h>
47
48 #include <dev/disk/mps/mpi/mpi2_type.h>
49 #include <dev/disk/mps/mpi/mpi2.h>
50 #include <dev/disk/mps/mpi/mpi2_ioc.h>
51 #include <dev/disk/mps/mpi/mpi2_cnfg.h>
52 #include <dev/disk/mps/mpi/mpi2_init.h>
53 #include <dev/disk/mps/mpsvar.h>
54 #include <dev/disk/mps/mps_table.h>
55
56 char *
57 mps_describe_table(struct mps_table_lookup *table, u_int code)
58 {
59         int i;
60
61         for (i = 0; table[i].string != NULL; i++) {
62                 if (table[i].code == code)
63                         return(table[i].string);
64         }
65         return(table[i+1].string);
66 }
67
68 struct mps_table_lookup mps_event_names[] = {
69         {"LogData",                     0x01},
70         {"StateChange",                 0x02},
71         {"HardResetReceived",           0x05},
72         {"EventChange",                 0x0a},
73         {"TaskSetFull",                 0x0e},
74         {"SasDeviceStatusChange",       0x0f},
75         {"IrOperationStatus",           0x14},
76         {"SasDiscovery",                0x16},
77         {"SasBroadcastPrimitive",       0x17},
78         {"SasInitDeviceStatusChange",   0x18},
79         {"SasInitTableOverflow",        0x19},
80         {"SasTopologyChangeList",       0x1c},
81         {"SasEnclDeviceStatusChange",   0x1d},
82         {"IrVolume",                    0x1e},
83         {"IrPhysicalDisk",              0x1f},
84         {"IrConfigurationChangeList",   0x20},
85         {"LogEntryAdded",               0x21},
86         {"SasPhyCounter",               0x22},
87         {"GpioInterrupt",               0x23},
88         {"HbdPhyEvent",                 0x24},
89         {NULL, 0},
90         {"Unknown Event", 0}
91 };
92
93 struct mps_table_lookup mps_phystatus_names[] = {
94         {"NewTargetAdded",              0x01},
95         {"TargetGone",                  0x02},
96         {"PHYLinkStatusChange",         0x03},
97         {"PHYLinkStatusUnchanged",      0x04},
98         {"TargetMissing",               0x05},
99         {NULL, 0},
100         {"Unknown Status", 0}
101 };
102
103 struct mps_table_lookup mps_linkrate_names[] = {
104         {"PHY disabled",                0x01},
105         {"Speed Negotiation Failed",    0x02},
106         {"SATA OOB Complete",           0x03},
107         {"SATA Port Selector",          0x04},
108         {"SMP Reset in Progress",       0x05},
109         {"1.5Gbps",                     0x08},
110         {"3.0Gbps",                     0x09},
111         {"6.0Gbps",                     0x0a},
112         {NULL, 0},
113         {"LinkRate Unknown",            0x00}
114 };
115
116 struct mps_table_lookup mps_sasdev0_devtype[] = {
117         {"End Device",                  0x01},
118         {"Edge Expander",               0x02},
119         {"Fanout Expander",             0x03},
120         {NULL, 0},
121         {"No Device",                   0x00}
122 };
123
124 struct mps_table_lookup mps_phyinfo_reason_names[] = {
125         {"Power On",                    0x01},
126         {"Hard Reset",                  0x02},
127         {"SMP Phy Control Link Reset",  0x03},
128         {"Loss DWORD Sync",             0x04},
129         {"Multiplex Sequence",          0x05},
130         {"I-T Nexus Loss Timer",        0x06},
131         {"Break Timeout Timer",         0x07},
132         {"PHY Test Function",           0x08},
133         {NULL, 0},
134         {"Unknown Reason",              0x00}
135 };
136
137 struct mps_table_lookup mps_whoinit_names[] = {
138         {"System BIOS",                 0x01},
139         {"ROM BIOS",                    0x02},
140         {"PCI Peer",                    0x03},
141         {"Host Driver",                 0x04},
142         {"Manufacturing",               0x05},
143         {NULL, 0},
144         {"Not Initialized",             0x00}
145 };
146
147 struct mps_table_lookup mps_sasdisc_reason[] = {
148         {"Discovery Started",           0x01},
149         {"Discovery Complete",          0x02},
150         {NULL, 0},
151         {"Unknown",                     0x00}
152 };
153
154 struct mps_table_lookup mps_sastopo_exp[] = {
155         {"Added",                       0x01},
156         {"Not Responding",              0x02},
157         {"Responding",                  0x03},
158         {"Delay Not Responding",        0x04},
159         {NULL, 0},
160         {"Unknown",                     0x00}
161 };
162
163 struct mps_table_lookup mps_sasdev_reason[] = {
164         {"SMART Data",                  0x05},
165         {"Unsupported",                 0x07},
166         {"Internal Device Reset",       0x08},
167         {"Task Abort Internal",         0x09},
168         {"Abort Task Set Internal",     0x0a},
169         {"Clear Task Set Internal",     0x0b},
170         {"Query Task Internal",         0x0c},
171         {"Async Notification",          0x0d},
172         {"Cmp Internal Device Reset",   0x0e},
173         {"Cmp Task Abort Internal",     0x0f},
174         {"Sata Init Failure",           0x10},
175         {NULL, 0},
176         {"Unknown",                     0x00}
177 };
178
179 void
180 mps_describe_devinfo(uint32_t devinfo, char *string, int len)
181 {
182         ksnprintf(string, len, "%b,%s", devinfo,
183             "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
184             "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
185             "\15LsiDev" "\16AtapiDev" "\17SepDev",
186             mps_describe_table(mps_sasdev0_devtype, devinfo & 0x03));
187 }
188
189 void
190 mps_print_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts)
191 {
192
193         MPS_PRINTFIELD_START(sc, "IOCFacts");
194         MPS_PRINTFIELD(sc, facts, MsgVersion, 0x%x);
195         MPS_PRINTFIELD(sc, facts, HeaderVersion, 0x%x);
196         MPS_PRINTFIELD(sc, facts, IOCNumber, %d);
197         MPS_PRINTFIELD(sc, facts, IOCExceptions, 0x%x);
198         MPS_PRINTFIELD(sc, facts, MaxChainDepth, %d);
199         mps_dprint_field(sc, MPS_INFO, "WhoInit: %s\n",
200             mps_describe_table(mps_whoinit_names, facts->WhoInit));
201         MPS_PRINTFIELD(sc, facts, NumberOfPorts, %d);
202         MPS_PRINTFIELD(sc, facts, RequestCredit, %d);
203         MPS_PRINTFIELD(sc, facts, ProductID, 0x%x);
204         mps_dprint_field(sc, MPS_INFO, "IOCCapabilities: %b\n",
205             (u_int)facts->IOCCapabilities, "\20" "\3ScsiTaskFull" "\4DiagTrace"
206             "\5SnapBuf" "\6ExtBuf" "\7EEDP" "\10BiDirTarg" "\11Multicast"
207             "\14TransRetry" "\15IR" "\16EventReplay" "\17RaidAccel"
208             "\20MSIXIndex" "\21HostDisc");
209         mps_dprint_field(sc, MPS_INFO, "FWVersion= %d-%d-%d-%d\n",
210             facts->FWVersion.Struct.Major,
211             facts->FWVersion.Struct.Minor,
212             facts->FWVersion.Struct.Unit,
213             facts->FWVersion.Struct.Dev);
214         MPS_PRINTFIELD(sc, facts, IOCRequestFrameSize, %d);
215         MPS_PRINTFIELD(sc, facts, MaxInitiators, %d);
216         MPS_PRINTFIELD(sc, facts, MaxTargets, %d);
217         MPS_PRINTFIELD(sc, facts, MaxSasExpanders, %d);
218         MPS_PRINTFIELD(sc, facts, MaxEnclosures, %d);
219         mps_dprint_field(sc, MPS_INFO, "ProtocolFlags: %b\n",
220             facts->ProtocolFlags, "\20" "\1ScsiTarg" "\2ScsiInit");
221         MPS_PRINTFIELD(sc, facts, HighPriorityCredit, %d);
222         MPS_PRINTFIELD(sc, facts, MaxReplyDescriptorPostQueueDepth, %d);
223         MPS_PRINTFIELD(sc, facts, ReplyFrameSize, %d);
224         MPS_PRINTFIELD(sc, facts, MaxVolumes, %d);
225         MPS_PRINTFIELD(sc, facts, MaxDevHandle, %d);
226         MPS_PRINTFIELD(sc, facts, MaxPersistentEntries, %d);
227 }
228
229 void
230 mps_print_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts)
231 {
232
233         MPS_PRINTFIELD_START(sc, "PortFacts");
234         MPS_PRINTFIELD(sc, facts, PortNumber, %d);
235         MPS_PRINTFIELD(sc, facts, PortType, 0x%x);
236         MPS_PRINTFIELD(sc, facts, MaxPostedCmdBuffers, %d);
237 }
238
239 void
240 mps_print_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
241 {
242
243         MPS_EVENTFIELD_START(sc, "EventReply");
244         MPS_EVENTFIELD(sc, event, EventDataLength, %d);
245         MPS_EVENTFIELD(sc, event, AckRequired, %d);
246         mps_dprint_field(sc, MPS_EVENT, "Event: %s (0x%x)\n",
247             mps_describe_table(mps_event_names, event->Event), event->Event);
248         mps_dprint_field(sc, MPS_EVENT, "EventContext: 0x%x\n",
249             (u_int)event->EventContext);
250 }
251
252 void
253 mps_print_sasdev0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_DEV_0 *buf)
254 {
255         MPS_PRINTFIELD_START(sc, "SAS Device Page 0");
256         MPS_PRINTFIELD(sc, buf, Slot, %d);
257         MPS_PRINTFIELD(sc, buf, EnclosureHandle, 0x%x);
258         mps_dprint_field(sc, MPS_INFO, "SASAddress: 0x%jx\n",
259             mps_to_u64(&buf->SASAddress));
260         MPS_PRINTFIELD(sc, buf, ParentDevHandle, 0x%x);
261         MPS_PRINTFIELD(sc, buf, PhyNum, %d);
262         MPS_PRINTFIELD(sc, buf, AccessStatus, 0x%x);
263         MPS_PRINTFIELD(sc, buf, DevHandle, 0x%x);
264         MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, 0x%x);
265         MPS_PRINTFIELD(sc, buf, ZoneGroup, %d);
266         mps_dprint_field(sc, MPS_INFO, "DeviceInfo: %b,%s\n",
267             (u_int)buf->DeviceInfo,
268             "\20" "\4SataHost" "\5SmpInit" "\6StpInit" "\7SspInit"
269             "\10SataDev" "\11SmpTarg" "\12StpTarg" "\13SspTarg" "\14Direct"
270             "\15LsiDev" "\16AtapiDev" "\17SepDev",
271             mps_describe_table(mps_sasdev0_devtype, buf->DeviceInfo & 0x03));
272         MPS_PRINTFIELD(sc, buf, Flags, 0x%x);
273         MPS_PRINTFIELD(sc, buf, PhysicalPort, %d);
274         MPS_PRINTFIELD(sc, buf, MaxPortConnections, %d);
275         mps_dprint_field(sc, MPS_INFO, "DeviceName: 0x%jx\n",
276             mps_to_u64(&buf->DeviceName));
277         MPS_PRINTFIELD(sc, buf, PortGroups, %d);
278         MPS_PRINTFIELD(sc, buf, DmaGroup, %d);
279         MPS_PRINTFIELD(sc, buf, ControlGroup, %d);
280 }
281
282 void
283 mps_print_evt_sas(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event)
284 {
285
286         mps_print_event(sc, event);
287
288         switch(event->Event) {
289         case MPI2_EVENT_SAS_DISCOVERY:
290         {
291                 MPI2_EVENT_DATA_SAS_DISCOVERY *data;
292
293                 data = (MPI2_EVENT_DATA_SAS_DISCOVERY *)&event->EventData;
294                 mps_dprint_field(sc, MPS_EVENT, "Flags: %b\n", data->Flags,
295                     "\20" "\1InProgress" "\2DeviceChange");
296                 mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
297                     mps_describe_table(mps_sasdisc_reason, data->ReasonCode));
298                 MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
299                 mps_dprint_field(sc, MPS_EVENT, "DiscoveryStatus: %b\n",
300                     (u_int)data->DiscoveryStatus,  "\20"
301                     "\1Loop" "\2UnaddressableDev" "\3DupSasAddr" "\5SmpTimeout"
302                     "\6ExpRouteFull" "\7RouteIndexError" "\10SmpFailed"
303                     "\11SmpCrcError" "\12SubSubLink" "\13TableTableLink"
304                     "\14UnsupDevice" "\15TableSubLink" "\16MultiDomain"
305                     "\17MultiSub" "\20MultiSubSub" "\34DownstreamInit"
306                     "\35MaxPhys" "\36MaxTargs" "\37MaxExpanders"
307                     "\40MaxEnclosures");
308                 break;
309         }
310         case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
311         {
312                 MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *data;
313                 MPI2_EVENT_SAS_TOPO_PHY_ENTRY *phy;
314                 int i, phynum;
315
316                 data = (MPI2_EVENT_DATA_SAS_TOPOLOGY_CHANGE_LIST *)
317                     &event->EventData;
318                 MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
319                 MPS_EVENTFIELD(sc, data, ExpanderDevHandle, 0x%x);
320                 MPS_EVENTFIELD(sc, data, NumPhys, %d);
321                 MPS_EVENTFIELD(sc, data, NumEntries, %d);
322                 MPS_EVENTFIELD(sc, data, StartPhyNum, %d);
323                 mps_dprint_field(sc, MPS_EVENT, "ExpStatus: %s (0x%x)\n",
324                     mps_describe_table(mps_sastopo_exp, data->ExpStatus),
325                     data->ExpStatus);
326                 MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
327                 for (i = 0; i < data->NumEntries; i++) {
328                         phy = &data->PHY[i];
329                         phynum = data->StartPhyNum + i;
330                         mps_dprint_field(sc, MPS_EVENT,
331                             "PHY[%d].AttachedDevHandle: 0x%04x\n", phynum,
332                             phy->AttachedDevHandle);
333                         mps_dprint_field(sc, MPS_EVENT,
334                             "PHY[%d].LinkRate: %s (0x%x)\n", phynum,
335                             mps_describe_table(mps_linkrate_names,
336                             (phy->LinkRate >> 4) & 0xf), phy->LinkRate);
337                         mps_dprint_field(sc,MPS_EVENT,"PHY[%d].PhyStatus: %s\n",
338                             phynum, mps_describe_table(mps_phystatus_names,
339                             phy->PhyStatus));
340                 }
341                 break;
342         }
343         case MPI2_EVENT_SAS_ENCL_DEVICE_STATUS_CHANGE:
344         {
345                 MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *data;
346
347                 data = (MPI2_EVENT_DATA_SAS_ENCL_DEV_STATUS_CHANGE *)
348                     &event->EventData;
349                 MPS_EVENTFIELD(sc, data, EnclosureHandle, 0x%x);
350                 mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
351                     mps_describe_table(mps_sastopo_exp, data->ReasonCode));
352                 MPS_EVENTFIELD(sc, data, PhysicalPort, %d);
353                 MPS_EVENTFIELD(sc, data, NumSlots, %d);
354                 MPS_EVENTFIELD(sc, data, StartSlot, %d);
355                 mps_dprint_field(sc, MPS_EVENT, "PhyBits: 0x%x\n",
356                     (u_int)data->PhyBits);
357                 break;
358         }
359         case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
360         {
361                 MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *data;
362
363                 data = (MPI2_EVENT_DATA_SAS_DEVICE_STATUS_CHANGE *)
364                     &event->EventData;
365                 MPS_EVENTFIELD(sc, data, TaskTag, 0x%x);
366                 mps_dprint_field(sc, MPS_EVENT, "ReasonCode: %s\n",
367                     mps_describe_table(mps_sasdev_reason, data->ReasonCode));
368                 MPS_EVENTFIELD(sc, data, ASC, 0x%x);
369                 MPS_EVENTFIELD(sc, data, ASCQ, 0x%x);
370                 MPS_EVENTFIELD(sc, data, DevHandle, 0x%x);
371                 mps_dprint_field(sc, MPS_EVENT, "SASAddress: 0x%jx\n",
372                     mps_to_u64(&data->SASAddress));
373         }
374         default:
375                 break;
376         }
377 }
378
379 void
380 mps_print_expander1(struct mps_softc *sc, MPI2_CONFIG_PAGE_EXPANDER_1 *buf)
381 {
382         MPS_PRINTFIELD_START(sc, "SAS Expander Page 1 #%d", buf->Phy);
383         MPS_PRINTFIELD(sc, buf, PhysicalPort, %d);
384         MPS_PRINTFIELD(sc, buf, NumPhys, %d);
385         MPS_PRINTFIELD(sc, buf, Phy, %d);
386         MPS_PRINTFIELD(sc, buf, NumTableEntriesProgrammed, %d);
387         mps_dprint_field(sc, MPS_INFO, "ProgrammedLinkRate: %s (0x%x)\n",
388             mps_describe_table(mps_linkrate_names,
389             (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
390         mps_dprint_field(sc, MPS_INFO, "HwLinkRate: %s (0x%x)\n",
391             mps_describe_table(mps_linkrate_names,
392             (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
393         MPS_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
394         mps_dprint_field(sc, MPS_INFO, "PhyInfo Reason: %s (0x%x)\n",
395             mps_describe_table(mps_phyinfo_reason_names,
396             (buf->PhyInfo >> 16) & 0xf), (u_int)buf->PhyInfo);
397         mps_dprint_field(sc, MPS_INFO, "AttachedDeviceInfo: %b,%s\n",
398             (u_int)buf->AttachedDeviceInfo,
399             "\20" "\4SATAhost" "\5SMPinit" "\6STPinit"
400             "\7SSPinit" "\10SATAdev" "\11SMPtarg" "\12STPtarg" "\13SSPtarg"
401             "\14Direct" "\15LSIdev" "\16ATAPIdev" "\17SEPdev",
402             mps_describe_table(mps_sasdev0_devtype,
403             buf->AttachedDeviceInfo & 0x03));
404         MPS_PRINTFIELD(sc, buf, ExpanderDevHandle, 0x%04x);
405         MPS_PRINTFIELD(sc, buf, ChangeCount, %d);
406         mps_dprint_field(sc, MPS_INFO, "NegotiatedLinkRate: %s (0x%x)\n",
407             mps_describe_table(mps_linkrate_names,
408             buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
409         MPS_PRINTFIELD(sc, buf, PhyIdentifier, %d);
410         MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
411         mps_dprint_field(sc, MPS_INFO, "DiscoveryInfo: 0x%x\n",
412             (u_int)buf->DiscoveryInfo);
413         mps_dprint_field(sc, MPS_INFO, "AttachedPhyInfo: 0x%x\n",
414             (u_int)buf->AttachedPhyInfo);
415         mps_dprint_field(sc, MPS_INFO, "AttachedPhyInfo Reason: %s (0x%x)\n",
416             mps_describe_table(mps_phyinfo_reason_names,
417             buf->AttachedPhyInfo & 0xf), (u_int)buf->AttachedPhyInfo);
418         MPS_PRINTFIELD(sc, buf, ZoneGroup, %d);
419         MPS_PRINTFIELD(sc, buf, SelfConfigStatus, 0x%x);
420 }
421
422 void
423 mps_print_sasphy0(struct mps_softc *sc, MPI2_CONFIG_PAGE_SAS_PHY_0 *buf)
424 {
425         MPS_PRINTFIELD_START(sc, "SAS PHY Page 0");
426         MPS_PRINTFIELD(sc, buf, OwnerDevHandle, 0x%04x);
427         MPS_PRINTFIELD(sc, buf, AttachedDevHandle, 0x%04x);
428         MPS_PRINTFIELD(sc, buf, AttachedPhyIdentifier, %d);
429         mps_dprint_field(sc, MPS_INFO, "AttachedPhyInfo Reason: %s (0x%x)\n",
430             mps_describe_table(mps_phyinfo_reason_names,
431             buf->AttachedPhyInfo & 0xf), (u_int)buf->AttachedPhyInfo);
432         mps_dprint_field(sc, MPS_INFO, "ProgrammedLinkRate: %s (0x%x)\n",
433             mps_describe_table(mps_linkrate_names,
434             (buf->ProgrammedLinkRate >> 4) & 0xf), buf->ProgrammedLinkRate);
435         mps_dprint_field(sc, MPS_INFO, "HwLinkRate: %s (0x%x)\n",
436             mps_describe_table(mps_linkrate_names,
437             (buf->HwLinkRate >> 4) & 0xf), buf->HwLinkRate);
438         MPS_PRINTFIELD(sc, buf, ChangeCount, %d);
439         MPS_PRINTFIELD(sc, buf, Flags, 0x%x);
440         mps_dprint_field(sc, MPS_INFO, "PhyInfo Reason: %s (0x%x)\n",
441             mps_describe_table(mps_phyinfo_reason_names,
442             (buf->PhyInfo >> 16) & 0xf), (u_int)buf->PhyInfo);
443         mps_dprint_field(sc, MPS_INFO, "NegotiatedLinkRate: %s (0x%x)\n",
444             mps_describe_table(mps_linkrate_names,
445             buf->NegotiatedLinkRate & 0xf), buf->NegotiatedLinkRate);
446 }
447
448 void
449 mps_print_sgl(struct mps_softc *sc, struct mps_command *cm, int offset)
450 {
451         MPI2_SGE_SIMPLE64 *sge;
452         MPI2_SGE_CHAIN32 *sgc;
453         MPI2_REQUEST_HEADER *req;
454         struct mps_chain *chain = NULL;
455         char *frame;
456         u_int i = 0, flags;
457
458         req = (MPI2_REQUEST_HEADER *)cm->cm_req;
459         frame = (char *)cm->cm_req;
460         sge = (MPI2_SGE_SIMPLE64 *)&frame[offset * 4];
461         kprintf("SGL for command %p\n", cm);
462
463         while (frame != NULL) {
464                 flags = sge->FlagsLength >> MPI2_SGE_FLAGS_SHIFT;
465                 kprintf("seg%d flags=0x%x len=0x%lx addr=0x%jx\n", i, flags,
466                     sge->FlagsLength & 0xffffff, mps_to_u64(&sge->Address));
467                 if (flags & (MPI2_SGE_FLAGS_END_OF_LIST |
468                     MPI2_SGE_FLAGS_END_OF_BUFFER))
469                         break;
470                 sge++;
471                 i++;
472                 if (flags & MPI2_SGE_FLAGS_LAST_ELEMENT) {
473                         sgc = (MPI2_SGE_CHAIN32 *)sge;
474                         kprintf("chain flags=0x%x len=0x%x Offset=0x%x "
475                             "Address=0x%x\n", sgc->Flags, sgc->Length,
476                             sgc->NextChainOffset, (u_int)sgc->Address);
477                         if (chain == NULL)
478                                 chain = TAILQ_FIRST(&cm->cm_chain_list);
479                         else
480                                 chain = TAILQ_NEXT(chain, chain_link);
481                         frame = (char *)chain->chain;
482                         sge = (MPI2_SGE_SIMPLE64 *)frame;
483                         hexdump(frame, 128, NULL, 0);
484                 }
485         }
486 }
487
488 void
489 mps_print_scsiio_cmd(struct mps_softc *sc, struct mps_command *cm)
490 {
491         MPI2_SCSI_IO_REQUEST *req;
492
493         req = (MPI2_SCSI_IO_REQUEST *)cm->cm_req;
494         mps_print_sgl(sc, cm, req->SGLOffset0);
495 }