2 * Copyright (c) 2015 Netflix, Inc.
3 * Written by: Scott Long <scottl@freebsd.org>
5 * Copyright (c) 2008 Yahoo!, Inc.
7 * Written by: John Baldwin <jhb@FreeBSD.org>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <sys/cdefs.h>
37 #include <sys/param.h>
38 #include <sys/errno.h>
39 #include <sys/endian.h>
48 static char * get_device_speed(uint8_t rate);
49 static char * get_device_type(uint32_t di);
50 static int show_all(int ac, char **av);
51 static int show_devices(int ac, char **av);
52 static int show_enclosures(int ac, char **av);
53 static int show_expanders(int ac, char **av);
57 #define STANDALONE_STATE "ONLINE"
60 show_adapter(int ac, char **av)
62 const char* pcie_speed[] = { "2.5", "5.0", "8.0" };
63 const char* temp_units[] = { "", "F", "C" };
64 const char* ioc_speeds[] = { "", "Full", "Half", "Quarter", "Eighth" };
66 MPI2_CONFIG_PAGE_SASIOUNIT_0 *sas0;
67 MPI2_CONFIG_PAGE_SASIOUNIT_1 *sas1;
68 MPI2_SAS_IO_UNIT0_PHY_DATA *phy0;
69 MPI2_SAS_IO_UNIT1_PHY_DATA *phy1;
70 MPI2_CONFIG_PAGE_MAN_0 *man0;
71 MPI2_CONFIG_PAGE_BIOS_3 *bios3;
72 MPI2_CONFIG_PAGE_IO_UNIT_1 *iounit1;
73 MPI2_CONFIG_PAGE_IO_UNIT_7 *iounit7;
74 MPI2_IOC_FACTS_REPLY *facts;
76 char *speed, *minspeed, *maxspeed, *isdisabled, *type;
77 char devhandle[8], ctrlhandle[8];
81 warnx("show adapter: extra arguments");
85 fd = mps_open(mps_unit);
92 man0 = mps_read_man_page(fd, 0, NULL);
95 warn("Failed to get controller info");
98 if (man0->Header.PageLength < sizeof(*man0) / 4) {
99 warnx("Invalid controller info");
102 printf("mp%s%d Adapter:\n", is_mps ? "s": "r", mps_unit);
103 printf(" Board Name: %.16s\n", man0->BoardName);
104 printf(" Board Assembly: %.16s\n", man0->BoardAssembly);
105 printf(" Chip Name: %.16s\n", man0->ChipName);
106 printf(" Chip Revision: %.16s\n", man0->ChipRevision);
109 bios3 = mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_BIOS, 3, 0, NULL);
112 warn("Failed to get BIOS page 3 info");
115 v = le32toh(bios3->BiosVersion);
116 printf(" BIOS Revision: %d.%02d.%02d.%02d\n",
117 ((v & 0xff000000) >> 24), ((v &0xff0000) >> 16),
118 ((v & 0xff00) >> 8), (v & 0xff));
121 if ((facts = mps_get_iocfacts(fd)) == NULL) {
122 printf("could not get controller IOCFacts\n");
126 v = facts->FWVersion.Word;
127 printf("Firmware Revision: %d.%02d.%02d.%02d\n",
128 ((v & 0xff000000) >> 24), ((v &0xff0000) >> 16),
129 ((v & 0xff00) >> 8), (v & 0xff));
130 printf(" Integrated RAID: %s\n",
131 (facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)
135 iounit1 = mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_IO_UNIT, 1, 0, NULL);
136 if (iounit1 == NULL) {
138 warn("Failed to get IOUNIT page 1 info");
141 printf(" SATA NCQ: %s\n",
142 ((iounit1->Flags & MPI2_IOUNITPAGE1_NATIVE_COMMAND_Q_DISABLE) == 0) ?
143 "ENABLED" : "DISABLED");
146 iounit7 = mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_IO_UNIT, 7, 0, NULL);
147 if (iounit7 == NULL) {
149 warn("Failed to get IOUNIT page 7 info");
152 printf(" PCIe Width/Speed: x%d (%s GB/sec)\n", iounit7->PCIeWidth,
153 pcie_speed[iounit7->PCIeSpeed]);
154 printf(" IOC Speed: %s\n", ioc_speeds[iounit7->IOCSpeed]);
155 printf(" Temperature: ");
156 if (iounit7->IOCTemperatureUnits == MPI2_IOUNITPAGE7_IOC_TEMP_NOT_PRESENT)
157 printf("Unknown/Unsupported\n");
159 printf("%d %s\n", iounit7->IOCTemperature,
160 temp_units[iounit7->IOCTemperatureUnits]);
163 fd = mps_open(mps_unit);
170 sas0 = mps_read_extended_config_page(fd,
171 MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
172 MPI2_SASIOUNITPAGE0_PAGEVERSION, 0, 0, &IOCStatus);
175 warn("Error retrieving SAS IO Unit page %d", IOCStatus);
181 sas1 = mps_read_extended_config_page(fd,
182 MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
183 MPI2_SASIOUNITPAGE1_PAGEVERSION, 1, 0, &IOCStatus);
186 warn("Error retrieving SAS IO Unit page %d", IOCStatus);
193 printf("%-8s%-12s%-11s%-10s%-8s%-7s%-7s%s\n", "PhyNum", "CtlrHandle",
194 "DevHandle", "Disabled", "Speed", "Min", "Max", "Device");
195 for (i = 0; i < sas0->NumPhys; i++) {
196 phy0 = &sas0->PhyData[i];
197 phy1 = &sas1->PhyData[i];
198 if (phy0->PortFlags &
199 MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
200 printf("Discovery still in progress\n");
203 if (phy0->PhyFlags & MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED)
208 minspeed = get_device_speed(phy1->MaxMinLinkRate);
209 maxspeed = get_device_speed(phy1->MaxMinLinkRate >> 4);
210 type = get_device_type(le32toh(phy0->ControllerPhyDeviceInfo));
212 if (le16toh(phy0->AttachedDevHandle) != 0) {
213 snprintf(devhandle, sizeof(devhandle), "%04x",
214 le16toh(phy0->AttachedDevHandle));
215 snprintf(ctrlhandle, sizeof(ctrlhandle), "%04x",
216 le16toh(phy0->ControllerDevHandle));
217 speed = get_device_speed(phy0->NegotiatedLinkRate);
219 snprintf(devhandle, sizeof(devhandle), " ");
220 snprintf(ctrlhandle, sizeof(ctrlhandle), " ");
223 printf("%-8d%-12s%-11s%-10s%-8s%-7s%-7s%s\n",
224 i, ctrlhandle, devhandle, isdisabled, speed, minspeed,
234 MPS_COMMAND(show, adapter, show_adapter, "", "display controller information")
237 show_iocfacts(int ac, char **av)
239 MPI2_IOC_FACTS_REPLY *facts;
244 fd = mps_open(mps_unit);
251 if ((facts = mps_get_iocfacts(fd)) == NULL) {
252 printf("could not get controller IOCFacts\n");
257 fb = (uint8_t *)facts;
259 #define IOCCAP "\3ScsiTaskFull" "\4DiagTrace" "\5SnapBuf" "\6ExtBuf" \
260 "\7EEDP" "\10BiDirTarg" "\11Multicast" "\14TransRetry" "\15IR" \
261 "\16EventReplay" "\17RaidAccel" "\20MSIXIndex" "\21HostDisc" \
262 "\22FastPath" "\23RDPQArray" "\24AtomicReqDesc" "\25PCIeSRIOV"
264 bzero(tmpbuf, sizeof(tmpbuf));
265 mps_parse_flags(facts->IOCCapabilities, IOCCAP, tmpbuf, sizeof(tmpbuf));
267 printf(" MsgVersion: %d.%d\n",
268 facts->MsgVersion >> 8, facts->MsgVersion & 0xff);
269 printf(" MsgLength: %d\n", facts->MsgLength);
270 printf(" Function: 0x%x\n", facts->Function);
271 printf(" HeaderVersion: %02d,%02d\n",
272 facts->HeaderVersion >> 8, facts->HeaderVersion & 0xff);
273 printf(" IOCNumber: %d\n", facts->IOCNumber);
274 printf(" MsgFlags: 0x%x\n", facts->MsgFlags);
275 printf(" VP_ID: %d\n", facts->VP_ID);
276 printf(" VF_ID: %d\n", facts->VF_ID);
277 printf(" IOCExceptions: %d\n", facts->IOCExceptions);
278 printf(" IOCStatus: %d\n", facts->IOCStatus);
279 printf(" IOCLogInfo: 0x%x\n", facts->IOCLogInfo);
280 printf(" MaxChainDepth: %d\n", facts->MaxChainDepth);
281 printf(" WhoInit: 0x%x\n", facts->WhoInit);
282 printf(" NumberOfPorts: %d\n", facts->NumberOfPorts);
283 printf(" MaxMSIxVectors: %d\n", facts->MaxMSIxVectors);
284 printf(" RequestCredit: %d\n", facts->RequestCredit);
285 printf(" ProductID: 0x%x\n", facts->ProductID);
286 printf(" IOCCapabilities: 0x%x %s\n", facts->IOCCapabilities,
288 printf(" FWVersion: %02d.%02d.%02d.%02d\n",
289 facts->FWVersion.Struct.Major, facts->FWVersion.Struct.Minor,
290 facts->FWVersion.Struct.Unit, facts->FWVersion.Struct.Dev);
291 printf(" IOCRequestFrameSize: %d\n", facts->IOCRequestFrameSize);
293 printf(" MaxChainSegmentSize: %d\n", (uint16_t)(fb[0x26]));
294 printf(" MaxInitiators: %d\n", facts->MaxInitiators);
295 printf(" MaxTargets: %d\n", facts->MaxTargets);
296 printf(" MaxSasExpanders: %d\n", facts->MaxSasExpanders);
297 printf(" MaxEnclosures: %d\n", facts->MaxEnclosures);
299 bzero(tmpbuf, sizeof(tmpbuf));
300 mps_parse_flags(facts->ProtocolFlags,
301 "\4NvmeDevices\2ScsiTarget\1ScsiInitiator", tmpbuf, sizeof(tmpbuf));
302 printf(" ProtocolFlags: 0x%x %s\n", facts->ProtocolFlags, tmpbuf);
303 printf(" HighPriorityCredit: %d\n", facts->HighPriorityCredit);
304 printf("MaxRepDescPostQDepth: %d\n",
305 facts->MaxReplyDescriptorPostQueueDepth);
306 printf(" ReplyFrameSize: %d\n", facts->ReplyFrameSize);
307 printf(" MaxVolumes: %d\n", facts->MaxVolumes);
308 printf(" MaxDevHandle: %d\n", facts->MaxDevHandle);
309 printf("MaxPersistentEntries: %d\n", facts->MaxPersistentEntries);
310 printf(" MinDevHandle: %d\n", facts->MinDevHandle);
312 printf(" CurrentHostPageSize: %d\n", (uint8_t)(fb[0x3e]));
318 MPS_COMMAND(show, iocfacts, show_iocfacts, "", "Show IOC Facts Message");
321 show_adapters(int ac, char **av)
323 MPI2_CONFIG_PAGE_MAN_0 *man0;
324 MPI2_IOC_FACTS_REPLY *facts;
327 printf("Device Name\t Chip Name Board Name Firmware\n");
328 for (unit = 0; unit < MPS_MAX_UNIT; unit++) {
332 facts = mps_get_iocfacts(fd);
335 warn("Faled to get controller iocfacts");
339 man0 = mps_read_man_page(fd, 0, NULL);
342 warn("Failed to get controller info");
347 if (man0->Header.PageLength < sizeof(*man0) / 4) {
348 warnx("Invalid controller info");
354 printf("/dev/mp%s%d\t%16s %16s %08x\n",
355 is_mps ? "s": "r", unit,
356 man0->ChipName, man0->BoardName, facts->FWVersion.Word);
363 MPS_COMMAND(show, adapters, show_adapters, "", "Show a summary of all adapters");
366 get_device_type(uint32_t di)
370 return ("SEP Target ");
372 return ("ATAPI Target ");
374 return ("SAS Target ");
376 return ("STP Target ");
378 return ("SMP Target ");
380 return ("SATA Target ");
382 return ("SAS Initiator ");
384 return ("SATA Initiator");
386 return ("No Device ");
387 return ("Unknown Device");
391 get_enc_type(uint32_t flags, int *issep)
396 switch (flags & 0xf) {
398 type = "Direct Attached SES-2";
402 type = "Direct Attached SGPIO";
405 type = "Expander SGPIO";
408 type = "External SES-2";
412 type = "Direct Attached GPIO";
423 mps_device_speed[] = {
439 get_device_speed(uint8_t rate)
444 if (rate >= sizeof(mps_device_speed))
447 if ((speed = mps_device_speed[rate]) == NULL)
464 "RAID Physical Disk",
476 "RAID Configuration",
477 "Driver Persistent Mapping",
480 "Extended Manufacturing"
484 get_page_name(u_int page)
488 if (page >= sizeof(mps_page_name))
490 if ((name = mps_page_name[page]) == NULL)
496 show_all(int ac, char **av)
500 printf("Adapter:\n");
501 error = show_adapter(ac, av);
502 printf("Devices:\n");
503 error = show_devices(ac, av);
504 printf("Enclosures:\n");
505 error = show_enclosures(ac, av);
506 printf("Expanders:\n");
507 error = show_expanders(ac, av);
510 MPS_COMMAND(show, all, show_all, "", "Show all devices");
513 show_devices(int ac, char **av)
515 MPI2_CONFIG_PAGE_SASIOUNIT_0 *sas0;
516 MPI2_SAS_IO_UNIT0_PHY_DATA *phydata;
517 MPI2_CONFIG_PAGE_SAS_DEV_0 *device;
518 MPI2_CONFIG_PAGE_EXPANDER_1 *exp1;
519 uint16_t IOCStatus, handle, bus, target;
520 char *type, *speed, enchandle[8], slot[8], bt[16];
522 int fd, error, nphys;
524 fd = mps_open(mps_unit);
531 sas0 = mps_read_extended_config_page(fd,
532 MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
533 MPI2_SASIOUNITPAGE0_PAGEVERSION, 0, 0, &IOCStatus);
536 warn("Error retrieving SAS IO Unit page %d", IOCStatus);
539 nphys = sas0->NumPhys;
541 printf("B____%-5s%-17s%-8s%-10s%-14s%-6s%-5s%-6s%s\n",
542 "T", "SAS Address", "Handle", "Parent", "Device", "Speed",
543 "Enc", "Slot", "Wdt");
546 device = mps_read_extended_config_page(fd,
547 MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE,
548 MPI2_SASDEVICE0_PAGEVERSION, 0,
549 MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE | handle,
551 if (device == NULL) {
552 if (IOCStatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
555 warn("Error retrieving device page");
559 handle = le16toh(device->DevHandle);
561 if (device->ParentDevHandle == 0x0) {
568 error = mps_map_btdh(fd, &handle, &bus, &target);
573 if ((bus == 0xffff) || (target == 0xffff))
574 snprintf(bt, sizeof(bt), " ");
576 snprintf(bt, sizeof(bt), "%02d %02d", bus, target);
578 type = get_device_type(le32toh(device->DeviceInfo));
580 if (device->DeviceInfo & 0x800) { /* Direct Attached */
581 if (device->PhyNum < nphys) {
582 phydata = &sas0->PhyData[device->PhyNum];
583 speed = get_device_speed(phydata->NegotiatedLinkRate);
586 } else if (device->ParentDevHandle > 0) {
587 exp1 = mps_read_extended_config_page(fd,
588 MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER,
589 MPI2_SASEXPANDER1_PAGEVERSION, 1,
590 MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
592 MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
593 le16toh(device->ParentDevHandle), &IOCStatus);
595 if (IOCStatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
597 warn("Error retrieving expander page 1: 0x%x",
605 speed = get_device_speed(exp1->NegotiatedLinkRate);
611 if (device->EnclosureHandle != 0) {
612 snprintf(enchandle, sizeof(enchandle), "%04x", le16toh(device->EnclosureHandle));
613 snprintf(slot, sizeof(slot), "%02d", le16toh(device->Slot));
615 snprintf(enchandle, sizeof(enchandle), " ");
616 snprintf(slot, sizeof(slot), " ");
619 snprintf(buf, sizeof(buf), "%08x%08x", le32toh(device->SASAddress.High),
620 le32toh(device->SASAddress.Low));
621 printf("%-17s", buf);
622 snprintf(buf, sizeof(buf), "%04x", le16toh(device->DevHandle));
624 snprintf(buf, sizeof(buf), "%04x", le16toh(device->ParentDevHandle));
625 printf("%-10s", buf);
626 printf("%-14s%-6s%-5s%-6s%d\n", type, speed,
627 enchandle, slot, device->MaxPortConnections);
635 MPS_COMMAND(show, devices, show_devices, "", "Show attached devices");
638 show_enclosures(int ac, char **av)
640 MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 *enc;
641 char *type, sepstr[8];
642 uint16_t IOCStatus, handle;
643 int fd, error, issep;
645 fd = mps_open(mps_unit);
652 printf("Slots Logical ID SEPHandle EncHandle Type\n");
655 enc = mps_read_extended_config_page(fd,
656 MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE,
657 MPI2_SASENCLOSURE0_PAGEVERSION, 0,
658 MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE | handle,
661 if (IOCStatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
664 warn("Error retrieving enclosure page");
668 type = get_enc_type(le16toh(enc->Flags), &issep);
670 snprintf(sepstr, sizeof(sepstr), " ");
672 snprintf(sepstr, sizeof(sepstr), "%04x", le16toh(enc->SEPDevHandle));
673 printf(" %.2d %08x%08x %s %04x %s\n",
674 le16toh(enc->NumSlots), le32toh(enc->EnclosureLogicalID.High),
675 le32toh(enc->EnclosureLogicalID.Low), sepstr, le16toh(enc->EnclosureHandle),
677 handle = le16toh(enc->EnclosureHandle);
684 MPS_COMMAND(show, enclosures, show_enclosures, "", "Show attached enclosures");
687 show_expanders(int ac, char **av)
689 MPI2_CONFIG_PAGE_EXPANDER_0 *exp0;
690 MPI2_CONFIG_PAGE_EXPANDER_1 *exp1;
691 uint16_t IOCStatus, handle;
692 char enchandle[8], parent[8], rphy[4], rhandle[8];
693 char *speed, *min, *max, *type;
694 int fd, error, nphys, i;
696 fd = mps_open(mps_unit);
703 printf("NumPhys SAS Address DevHandle Parent EncHandle SAS Level\n");
706 exp0 = mps_read_extended_config_page(fd,
707 MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER,
708 MPI2_SASEXPANDER0_PAGEVERSION, 0,
709 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL | handle,
712 if (IOCStatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
715 warn("Error retrieving expander page 0");
720 nphys = exp0->NumPhys;
721 handle = le16toh(exp0->DevHandle);
723 if (exp0->EnclosureHandle == 0x00)
724 snprintf(enchandle, sizeof(enchandle), " ");
726 snprintf(enchandle, sizeof(enchandle), "%04d", le16toh(exp0->EnclosureHandle));
727 if (exp0->ParentDevHandle == 0x0)
728 snprintf(parent, sizeof(parent), " ");
730 snprintf(parent, sizeof(parent), "%04x", le16toh(exp0->ParentDevHandle));
731 printf(" %02d %08x%08x %04x %s %s %d\n",
732 exp0->NumPhys, le32toh(exp0->SASAddress.High), le32toh(exp0->SASAddress.Low),
733 le16toh(exp0->DevHandle), parent, enchandle, exp0->SASLevel);
736 printf(" Phy RemotePhy DevHandle Speed Min Max Device\n");
737 for (i = 0; i < nphys; i++) {
738 exp1 = mps_read_extended_config_page(fd,
739 MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER,
740 MPI2_SASEXPANDER1_PAGEVERSION, 1,
741 MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
742 (i << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
743 exp0->DevHandle, &IOCStatus);
746 MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
747 warn("Error retrieving expander pg 1");
750 type = get_device_type(le32toh(exp1->AttachedDeviceInfo));
751 if ((le32toh(exp1->AttachedDeviceInfo) &0x7) == 0) {
753 snprintf(rphy, sizeof(rphy), " ");
754 snprintf(rhandle, sizeof(rhandle), " ");
756 speed = get_device_speed(
757 exp1->NegotiatedLinkRate);
758 snprintf(rphy, sizeof(rphy), "%02d",
759 exp1->AttachedPhyIdentifier);
760 snprintf(rhandle, sizeof(rhandle), "%04x",
761 le16toh(exp1->AttachedDevHandle));
763 min = get_device_speed(exp1->HwLinkRate);
764 max = get_device_speed(exp1->HwLinkRate >> 4);
765 printf(" %02d %s %s %s %s %s %s\n", exp1->Phy, rphy, rhandle, speed, min, max, type);
777 MPS_COMMAND(show, expanders, show_expanders, "", "Show attached expanders");
780 show_cfgpage(int ac, char **av)
782 MPI2_CONFIG_PAGE_HEADER *hdr;
783 MPI2_CONFIG_EXTENDED_PAGE_HEADER *ehdr;
788 int fd, error, len, attrs;
789 char *pgname, *pgattr;
791 fd = mps_open(mps_unit);
804 addr = htole32((uint32_t)strtoul(av[3], NULL, 0));
806 num = (uint8_t)strtoul(av[2], NULL, 0);
808 page = (uint8_t)strtoul(av[1], NULL, 0);
812 warn("cfgpage: not enough arguments");
817 data = mps_read_extended_config_page(fd, page, 0, num, addr,
820 data = mps_read_config_page(fd, page, num, addr, &IOCStatus);
824 warn("Error retrieving cfg page: %s\n",
825 mps_ioc_status(IOCStatus));
831 len = le16toh(ehdr->ExtPageLength) * 4;
832 page = ehdr->ExtPageType;
833 attrs = ehdr->PageType >> 4;
836 len = hdr->PageLength * 4;
837 page = hdr->PageType & 0xf;
838 attrs = hdr->PageType >> 4;
841 pgname = get_page_name(page);
843 pgattr = "Read-only";
845 pgattr = "Read-Write";
847 pgattr = "Read-Write Persistent";
849 pgattr = "Unknown Page Attribute";
851 printf("Page 0x%x: %s %d, %s\n", page, pgname, num, pgattr);
852 hexdump(data, len, NULL, HD_REVERSED | 4);
858 MPS_COMMAND(show, cfgpage, show_cfgpage, "page [num] [addr]", "Display config page");