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