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