[Midnightbsd-cvs] src [10380] trunk/usr.sbin/mpsutil: add mpsutil

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sun Jun 3 19:26:14 EDT 2018


Revision: 10380
          http://svnweb.midnightbsd.org/src/?rev=10380
Author:   laffer1
Date:     2018-06-03 19:26:13 -0400 (Sun, 03 Jun 2018)
Log Message:
-----------
add mpsutil

Added Paths:
-----------
    trunk/usr.sbin/mpsutil/
    trunk/usr.sbin/mpsutil/Makefile
    trunk/usr.sbin/mpsutil/mpr_ioctl.h
    trunk/usr.sbin/mpsutil/mps_cmd.c
    trunk/usr.sbin/mpsutil/mps_flash.c
    trunk/usr.sbin/mpsutil/mps_ioctl.h
    trunk/usr.sbin/mpsutil/mps_show.c
    trunk/usr.sbin/mpsutil/mpsutil.8
    trunk/usr.sbin/mpsutil/mpsutil.c
    trunk/usr.sbin/mpsutil/mpsutil.h

Added: trunk/usr.sbin/mpsutil/Makefile
===================================================================
--- trunk/usr.sbin/mpsutil/Makefile	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/Makefile	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,22 @@
+# $MidnightBSD$
+# $FreeBSD: stable/10/usr.sbin/mpsutil/Makefile 297590 2016-04-05 20:34:20Z sbruno $
+
+PROG=	mpsutil
+SRCS=	mps_cmd.c mps_flash.c mps_show.c mpsutil.c
+MAN=	mpsutil.8
+
+WARNS?= 3
+
+#LIBADD=	cam util
+LINKS=	${BINDIR}/mpsutil ${BINDIR}/mprutil
+MLINKS=	mpsutil.8 mprutil.8
+
+CFLAGS+= -I${.CURDIR}/../../sys -I. -DUSE_MPT_IOCTLS
+
+
+# Here be dragons
+.ifdef DEBUG
+CFLAGS+= -DDEBUG
+.endif
+
+.include <bsd.prog.mk>


Property changes on: trunk/usr.sbin/mpsutil/Makefile
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mpr_ioctl.h
===================================================================
--- trunk/usr.sbin/mpsutil/mpr_ioctl.h	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mpr_ioctl.h	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,389 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * LSI MPT-Fusion Host Adapter FreeBSD userland interface
+ *
+ * $FreeBSD: stable/10/usr.sbin/mpsutil/mpr_ioctl.h 297590 2016-04-05 20:34:20Z sbruno $
+ */
+/*-
+ * Copyright (c) 2011-2014 LSI Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * LSI MPT-Fusion Host Adapter FreeBSD
+ *
+ * $FreeBSD: stable/10/usr.sbin/mpsutil/mpr_ioctl.h 297590 2016-04-05 20:34:20Z sbruno $
+ */
+
+#ifndef _MPR_IOCTL_H_
+#define	_MPR_IOCTL_H_
+
+#include <dev/mpr/mpi/mpi2_type.h>
+#include <dev/mpr/mpi/mpi2.h>
+#include <dev/mpr/mpi/mpi2_cnfg.h>
+#include <dev/mpr/mpi/mpi2_sas.h>
+
+/*
+ * For the read header requests, the header should include the page
+ * type or extended page type, page number, and page version.  The
+ * buffer and length are unused.  The completed header is returned in
+ * the 'header' member.
+ *
+ * For the read page and write page requests, 'buf' should point to a
+ * buffer of 'len' bytes which holds the entire page (including the
+ * header).
+ *
+ * All requests specify the page address in 'page_address'.
+ */
+struct mpr_cfg_page_req {	
+	MPI2_CONFIG_PAGE_HEADER header;
+	uint32_t page_address;
+	void	*buf;
+	int	len;
+	uint16_t ioc_status;
+};
+
+struct mpr_ext_cfg_page_req {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER header;
+	uint32_t page_address;
+	void	*buf;
+	int	len;
+	uint16_t ioc_status;
+};
+
+struct mpr_raid_action {
+	uint8_t action;
+	uint8_t volume_bus;
+	uint8_t volume_id;
+	uint8_t phys_disk_num;
+	uint32_t action_data_word;
+	void *buf;
+	int len;
+	uint32_t volume_status;
+	uint32_t action_data[4];
+	uint16_t action_status;
+	uint16_t ioc_status;
+	uint8_t write;
+};
+
+struct mpr_usr_command {
+	void *req;
+	uint32_t req_len;
+	void *rpl;
+	uint32_t rpl_len;
+	void *buf;
+	int len;
+	uint32_t flags;
+};
+
+typedef struct mpr_pci_bits
+{
+	union {
+		struct {
+			uint32_t	DeviceNumber	:5;
+			uint32_t	FunctionNumber	:3;
+			uint32_t	BusNumber	:24;
+		} bits;
+		uint32_t	AsDWORD;
+	} u;
+	uint32_t	PciSegmentId;
+} mpr_pci_bits_t;
+
+/*
+ *  The following is the MPRIOCTL_GET_ADAPTER_DATA data structure.  This data
+ *  structure is setup so that we hopefully are properly aligned for both
+ *  32-bit and 64-bit mode applications.
+ *
+ *  Adapter Type - Value = 6 = SCSI Protocol through SAS-3 adapter
+ *
+ *  MPI Port Number - The PCI Function number for this device
+ *
+ *  PCI Device HW Id - The PCI device number for this device
+ *
+ */
+#define	MPRIOCTL_ADAPTER_TYPE_SAS3		6
+typedef struct mpr_adapter_data
+{
+	uint32_t	StructureLength;
+	uint32_t	AdapterType;
+	uint32_t	MpiPortNumber;
+	uint32_t	PCIDeviceHwId;
+	uint32_t	PCIDeviceHwRev;
+	uint32_t	SubSystemId;
+	uint32_t	SubsystemVendorId;
+	uint32_t	Reserved1;
+	uint32_t	MpiFirmwareVersion;
+	uint32_t	BiosVersion;
+	uint8_t		DriverVersion[32];
+	uint8_t		Reserved2;
+	uint8_t		ScsiId;
+	uint16_t	Reserved3;
+	mpr_pci_bits_t	PciInformation;
+} mpr_adapter_data_t;
+
+
+typedef struct mpr_update_flash
+{
+	uint64_t	PtrBuffer;
+	uint32_t	ImageChecksum;
+	uint32_t	ImageOffset;
+	uint32_t	ImageSize;
+	uint32_t	ImageType;
+} mpr_update_flash_t;
+
+
+#define	MPR_PASS_THRU_DIRECTION_NONE	0
+#define	MPR_PASS_THRU_DIRECTION_READ	1
+#define	MPR_PASS_THRU_DIRECTION_WRITE	2
+#define	MPR_PASS_THRU_DIRECTION_BOTH	3
+
+typedef struct mpr_pass_thru
+{
+	uint64_t	PtrRequest;
+	uint64_t	PtrReply;
+	uint64_t	PtrData;
+	uint32_t	RequestSize;
+	uint32_t	ReplySize;
+	uint32_t	DataSize;
+	uint32_t	DataDirection;
+	uint64_t	PtrDataOut;
+	uint32_t	DataOutSize;
+	uint32_t	Timeout;
+} mpr_pass_thru_t;
+
+
+/*
+ * Event queue defines
+ */
+#define	MPR_EVENT_QUEUE_SIZE		(50) /* Max Events stored in driver */
+#define	MPR_MAX_EVENT_DATA_LENGTH	(48) /* Size of each event in Dwords */
+
+typedef struct mpr_event_query
+{
+	uint16_t	Entries;
+	uint16_t	Reserved;
+	uint32_t	Types[4];
+} mpr_event_query_t;
+
+typedef struct mpr_event_enable
+{
+	uint32_t	Types[4];
+} mpr_event_enable_t;
+
+/*
+ * Event record entry for ioctl.
+ */
+typedef struct mpr_event_entry
+{
+	uint32_t	Type;
+	uint32_t	Number;
+	uint32_t	Data[MPR_MAX_EVENT_DATA_LENGTH];
+} mpr_event_entry_t;
+
+typedef struct mpr_event_report
+{
+	uint32_t	Size;
+	uint64_t	PtrEvents;
+} mpr_event_report_t;
+
+
+typedef struct mpr_pci_info
+{
+	uint32_t	BusNumber;
+	uint8_t		DeviceNumber;
+	uint8_t		FunctionNumber;
+	uint16_t	InterruptVector;
+	uint8_t		PciHeader[256];
+} mpr_pci_info_t;
+
+
+typedef struct mpr_diag_action
+{
+	uint32_t	Action;
+	uint32_t	Length;
+	uint64_t	PtrDiagAction;
+	uint32_t	ReturnCode;
+} mpr_diag_action_t;
+
+#define	MPR_FW_DIAGNOSTIC_UID_NOT_FOUND	(0xFF)
+
+#define	MPR_FW_DIAG_NEW				(0x806E6577)
+
+#define	MPR_FW_DIAG_TYPE_REGISTER		(0x00000001)
+#define	MPR_FW_DIAG_TYPE_UNREGISTER		(0x00000002)
+#define	MPR_FW_DIAG_TYPE_QUERY			(0x00000003)
+#define	MPR_FW_DIAG_TYPE_READ_BUFFER		(0x00000004)
+#define	MPR_FW_DIAG_TYPE_RELEASE		(0x00000005)
+
+#define	MPR_FW_DIAG_INVALID_UID			(0x00000000)
+
+#define MPR_DIAG_SUCCESS			0
+#define MPR_DIAG_FAILURE			1
+
+#define	MPR_FW_DIAG_ERROR_SUCCESS		(0x00000000)
+#define	MPR_FW_DIAG_ERROR_FAILURE		(0x00000001)
+#define	MPR_FW_DIAG_ERROR_INVALID_PARAMETER	(0x00000002)
+#define	MPR_FW_DIAG_ERROR_POST_FAILED		(0x00000010)
+#define	MPR_FW_DIAG_ERROR_INVALID_UID		(0x00000011)
+#define	MPR_FW_DIAG_ERROR_RELEASE_FAILED	(0x00000012)
+#define	MPR_FW_DIAG_ERROR_NO_BUFFER		(0x00000013)
+#define	MPR_FW_DIAG_ERROR_ALREADY_RELEASED	(0x00000014)
+
+
+typedef struct mpr_fw_diag_register
+{
+	uint8_t		ExtendedType;
+	uint8_t		BufferType;
+	uint16_t	ApplicationFlags;
+	uint32_t	DiagnosticFlags;
+	uint32_t	ProductSpecific[23];
+	uint32_t	RequestedBufferSize;
+	uint32_t	UniqueId;
+} mpr_fw_diag_register_t;
+
+typedef struct mpr_fw_diag_unregister
+{
+	uint32_t	UniqueId;
+} mpr_fw_diag_unregister_t;
+
+#define	MPR_FW_DIAG_FLAG_APP_OWNED		(0x0001)
+#define	MPR_FW_DIAG_FLAG_BUFFER_VALID		(0x0002)
+#define	MPR_FW_DIAG_FLAG_FW_BUFFER_ACCESS	(0x0004)
+
+typedef struct mpr_fw_diag_query
+{
+	uint8_t		ExtendedType;
+	uint8_t		BufferType;
+	uint16_t	ApplicationFlags;
+	uint32_t	DiagnosticFlags;
+	uint32_t	ProductSpecific[23];
+	uint32_t	TotalBufferSize;
+	uint32_t	DriverAddedBufferSize;
+	uint32_t	UniqueId;
+} mpr_fw_diag_query_t;
+
+typedef struct mpr_fw_diag_release
+{
+	uint32_t	UniqueId;
+} mpr_fw_diag_release_t;
+
+#define	MPR_FW_DIAG_FLAG_REREGISTER	(0x0001)
+#define	MPR_FW_DIAG_FLAG_FORCE_RELEASE	(0x0002)
+
+typedef struct mpr_diag_read_buffer
+{
+	uint8_t		Status;
+	uint8_t		Reserved;
+	uint16_t	Flags;
+	uint32_t	StartingOffset;
+	uint32_t	BytesToRead;
+	uint32_t	UniqueId;
+	uint64_t	PtrDataBuffer;
+} mpr_diag_read_buffer_t;
+
+/*
+ * Register Access
+ */
+#define	REG_IO_READ	1
+#define	REG_IO_WRITE	2
+#define	REG_MEM_READ	3
+#define	REG_MEM_WRITE	4
+
+typedef struct mpr_reg_access
+{
+	uint32_t	Command;
+	uint32_t	RegOffset;
+	uint32_t	RegData;
+} mpr_reg_access_t;
+
+typedef struct mpr_btdh_mapping
+{
+	uint16_t	TargetID;
+	uint16_t	Bus;
+	uint16_t	DevHandle;
+	uint16_t	Reserved;
+} mpr_btdh_mapping_t;
+
+#define MPRIO_MPR_COMMAND_FLAG_VERBOSE	0x01
+#define MPRIO_MPR_COMMAND_FLAG_DEBUG	0x02
+#define	MPRIO_READ_CFG_HEADER	_IOWR('M', 200, struct mpr_cfg_page_req)
+#define	MPRIO_READ_CFG_PAGE	_IOWR('M', 201, struct mpr_cfg_page_req)
+#define	MPRIO_READ_EXT_CFG_HEADER _IOWR('M', 202, struct mpr_ext_cfg_page_req)
+#define	MPRIO_READ_EXT_CFG_PAGE	_IOWR('M', 203, struct mpr_ext_cfg_page_req)
+#define	MPRIO_WRITE_CFG_PAGE	_IOWR('M', 204, struct mpr_cfg_page_req)
+#define	MPRIO_RAID_ACTION	_IOWR('M', 205, struct mpr_raid_action)
+#define	MPRIO_MPR_COMMAND	_IOWR('M', 210, struct mpr_usr_command)
+
+#ifndef MPTIOCTL
+#define	MPTIOCTL			('I')
+#define	MPTIOCTL_GET_ADAPTER_DATA	_IOWR(MPTIOCTL, 1,\
+    struct mpr_adapter_data)
+#define	MPTIOCTL_UPDATE_FLASH		_IOWR(MPTIOCTL, 2,\
+    struct mpr_update_flash)
+#define	MPTIOCTL_RESET_ADAPTER		_IO(MPTIOCTL, 3)
+#define	MPTIOCTL_PASS_THRU		_IOWR(MPTIOCTL, 4,\
+    struct mpr_pass_thru)
+#define	MPTIOCTL_EVENT_QUERY		_IOWR(MPTIOCTL, 5,\
+    struct mpr_event_query)
+#define	MPTIOCTL_EVENT_ENABLE		_IOWR(MPTIOCTL, 6,\
+    struct mpr_event_enable)
+#define	MPTIOCTL_EVENT_REPORT		_IOWR(MPTIOCTL, 7,\
+    struct mpr_event_report)
+#define	MPTIOCTL_GET_PCI_INFO		_IOWR(MPTIOCTL, 8,\
+    struct mpr_pci_info)
+#define	MPTIOCTL_DIAG_ACTION		_IOWR(MPTIOCTL, 9,\
+    struct mpr_diag_action)
+#define	MPTIOCTL_REG_ACCESS		_IOWR(MPTIOCTL, 10,\
+    struct mpr_reg_access)
+#define	MPTIOCTL_BTDH_MAPPING		_IOWR(MPTIOCTL, 11,\
+    struct mpr_btdh_mapping)
+#endif
+
+#endif /* !_MPR_IOCTL_H_ */


Property changes on: trunk/usr.sbin/mpsutil/mpr_ioctl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mps_cmd.c
===================================================================
--- trunk/usr.sbin/mpsutil/mps_cmd.c	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mps_cmd.c	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,732 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Baptiste Daroussin <bapt at FreeBSD.org>
+ *
+ * Copyright (c) 2015 Netflix, Inc.
+ * All rights reserved.
+ * Written by: Scott Long <scottl at freebsd.org>
+ *
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$FreeBSD: stable/10/usr.sbin/mpsutil/mps_cmd.c 315600 2017-03-20 00:55:24Z pfg $");
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#if 0
+#include <sys/mps_ioctl.h>
+#else
+#include "mps_ioctl.h"
+#include "mpr_ioctl.h"
+#endif
+#include <sys/sysctl.h>
+#include <sys/uio.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "mpsutil.h"
+
+#ifndef USE_MPT_IOCTLS
+#define USE_MPT_IOCTLS
+#endif
+
+static const char *mps_ioc_status_codes[] = {
+	"Success",				/* 0x0000 */
+	"Invalid function",
+	"Busy",
+	"Invalid scatter-gather list",
+	"Internal error",
+	"Reserved",
+	"Insufficient resources",
+	"Invalid field",
+	"Invalid state",			/* 0x0008 */
+	"Operation state not supported",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,					/* 0x0010 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,					/* 0x0018 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"Invalid configuration action",		/* 0x0020 */
+	"Invalid configuration type",
+	"Invalid configuration page",
+	"Invalid configuration data",
+	"No configuration defaults",
+	"Unable to commit configuration change",
+	NULL,
+	NULL,
+	NULL,					/* 0x0028 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,					/* 0x0030 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,					/* 0x0038 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"Recovered SCSI error",			/* 0x0040 */
+	"Invalid SCSI bus",
+	"Invalid SCSI target ID",
+	"SCSI device not there",
+	"SCSI data overrun",
+	"SCSI data underrun",
+	"SCSI I/O error",
+	"SCSI protocol error",
+	"SCSI task terminated",			/* 0x0048 */
+	"SCSI residual mismatch",
+	"SCSI task management failed",
+	"SCSI I/O controller terminated",
+	"SCSI external controller terminated",
+	"EEDP guard error",
+	"EEDP reference tag error",
+	"EEDP application tag error",
+	NULL,					/* 0x0050 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,					/* 0x0058 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"SCSI target priority I/O",		/* 0x0060 */
+	"Invalid SCSI target port",
+	"Invalid SCSI target I/O index",
+	"SCSI target aborted",
+	"No connection retryable",
+	"No connection",
+	"FC aborted",
+	"Invalid FC receive ID",
+	"FC did invalid",			/* 0x0068 */
+	"FC node logged out",
+	"Transfer count mismatch",
+	"STS data not set",
+	"FC exchange canceled",
+	"Data offset error",
+	"Too much write data",
+	"IU too short",
+	"ACK NAK timeout",			/* 0x0070 */
+	"NAK received",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,					/* 0x0078 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"LAN device not found",			/* 0x0080 */
+	"LAN device failure",
+	"LAN transmit error",
+	"LAN transmit aborted",
+	"LAN receive error",
+	"LAN receive aborted",
+	"LAN partial packet",
+	"LAN canceled",
+	NULL,					/* 0x0088 */
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"SAS SMP request failed",		/* 0x0090 */
+	"SAS SMP data overrun",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"Inband aborted",			/* 0x0098 */
+	"No inband connection",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"Diagnostic released",			/* 0x00A0 */
+};
+
+struct mprs_pass_thru {
+        uint64_t        PtrRequest;
+        uint64_t        PtrReply;
+        uint64_t        PtrData;
+        uint32_t        RequestSize;
+        uint32_t        ReplySize;
+        uint32_t        DataSize;
+        uint32_t        DataDirection;
+        uint64_t        PtrDataOut;
+        uint32_t        DataOutSize;
+        uint32_t        Timeout;
+};
+
+struct mprs_btdh_mapping {
+        uint16_t        TargetID;
+        uint16_t        Bus;
+        uint16_t        DevHandle;
+        uint16_t        Reserved;
+};
+
+const char *
+mps_ioc_status(U16 IOCStatus)
+{
+	static char buffer[16];
+
+	IOCStatus &= MPI2_IOCSTATUS_MASK;
+	if (IOCStatus < sizeof(mps_ioc_status_codes) / sizeof(char *) &&
+	    mps_ioc_status_codes[IOCStatus] != NULL)
+		return (mps_ioc_status_codes[IOCStatus]);
+	snprintf(buffer, sizeof(buffer), "Status: 0x%04x", IOCStatus);
+	return (buffer);
+}
+
+#ifdef USE_MPT_IOCTLS
+int
+mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus, uint16_t *target)
+{
+	int error;
+	struct mprs_btdh_mapping map;
+
+	map.Bus = *bus;
+	map.TargetID = *target;
+	map.DevHandle = *devhandle;
+
+	if ((error = ioctl(fd, MPTIOCTL_BTDH_MAPPING, &map)) != 0) {
+		error = errno;
+		warn("Failed to map bus/target/device");
+		return (error);
+	}
+
+	*bus = map.Bus;
+	*target = map.TargetID;
+	*devhandle = map.DevHandle;
+
+	return (0);
+}
+
+int
+mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
+    MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus)
+{
+	MPI2_CONFIG_REQUEST req;
+	MPI2_CONFIG_REPLY reply;
+
+	bzero(&req, sizeof(req));
+	req.Function = MPI2_FUNCTION_CONFIG;
+	req.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	req.Header.PageType = PageType;
+	req.Header.PageNumber = PageNumber;
+	req.PageAddress = PageAddress;
+
+	if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    NULL, 0, NULL, 0, 30))
+		return (errno);
+
+	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = reply.IOCStatus;
+		return (EIO);
+	}
+	if (header == NULL)
+		return (EINVAL);
+	*header = reply.Header;
+	return (0);
+}
+
+int
+mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber, U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, U16 *ExtPageLength, U16 *IOCStatus)
+{
+	MPI2_CONFIG_REQUEST req;
+	MPI2_CONFIG_REPLY reply;
+
+	bzero(&req, sizeof(req));
+	req.Function = MPI2_FUNCTION_CONFIG;
+	req.Action = MPI2_CONFIG_ACTION_PAGE_HEADER;
+	req.Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED;
+	req.ExtPageType = ExtPageType;
+	req.Header.PageNumber = PageNumber;
+	req.PageAddress = PageAddress;
+
+	if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    NULL, 0, NULL, 0, 30))
+		return (errno);
+
+	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = reply.IOCStatus;
+		return (EIO);
+	}
+	if ((header == NULL) || (ExtPageLength == NULL))
+		return (EINVAL);
+	*header = reply.Header;
+	*ExtPageLength = reply.ExtPageLength;
+	return (0);
+}
+
+void *
+mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
+    U16 *IOCStatus)
+{
+	MPI2_CONFIG_REQUEST req;
+	MPI2_CONFIG_PAGE_HEADER header;
+	MPI2_CONFIG_REPLY reply;
+	void *buf;
+	int error, len;
+
+	bzero(&header, sizeof(header));
+	error = mps_read_config_page_header(fd, PageType, PageNumber,
+	    PageAddress, &header, IOCStatus);
+	if (error) {
+		errno = error;
+		return (NULL);
+	}
+
+	bzero(&req, sizeof(req));
+	req.Function = MPI2_FUNCTION_CONFIG;
+	req.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+	req.PageAddress = PageAddress;
+	req.Header = header;
+	req.Header.PageLength = reply.Header.PageLength;
+	if (reply.Header.PageLength == 0)
+		req.Header.PageLength = 4;
+
+	len = req.Header.PageLength * 4;
+	buf = malloc(len);
+	if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    buf, len, NULL, 0, 30)) {
+		error = errno;
+		free(buf);
+		errno = error;
+		return (NULL);
+	}
+	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = reply.IOCStatus;
+		else
+			warnx("Reading config page failed: 0x%x %s",
+			    reply.IOCStatus, mps_ioc_status(reply.IOCStatus));
+		free(buf);
+		errno = EIO;
+		return (NULL);
+	}
+	return (buf);
+}
+
+void *
+mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
+    U8 PageNumber, U32 PageAddress, U16 *IOCStatus)
+{
+	MPI2_CONFIG_REQUEST req;
+	MPI2_CONFIG_PAGE_HEADER header;
+	MPI2_CONFIG_REPLY reply;
+	U16 pagelen;
+	void *buf;
+	int error, len;
+
+	if (IOCStatus != NULL)
+		*IOCStatus = MPI2_IOCSTATUS_SUCCESS;
+	bzero(&header, sizeof(header));
+	error = mps_read_ext_config_page_header(fd, ExtPageType, PageNumber,
+	    PageAddress, &header, &pagelen, IOCStatus);
+	if (error) {
+		errno = error;
+		return (NULL);
+	}
+
+	bzero(&req, sizeof(req));
+	req.Function = MPI2_FUNCTION_CONFIG;
+	req.Action = MPI2_CONFIG_ACTION_PAGE_READ_CURRENT;
+	req.PageAddress = PageAddress;
+	req.Header = header;
+	if (pagelen == 0)
+		pagelen = 4;
+	req.ExtPageLength = pagelen;
+	req.ExtPageType = ExtPageType;
+
+	len = pagelen * 4;
+	buf = malloc(len);
+	if (mps_pass_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    buf, len, NULL, 0, 30)) {
+		error = errno;
+		free(buf);
+		errno = error;
+		return (NULL);
+	}
+	if (!IOC_STATUS_SUCCESS(reply.IOCStatus)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = reply.IOCStatus;
+		else
+			warnx("Reading extended config page failed: %s",
+			    mps_ioc_status(reply.IOCStatus));
+		free(buf);
+		errno = EIO;
+		return (NULL);
+	}
+	return (buf);
+}
+
+int
+mps_firmware_send(int fd, unsigned char *fw, uint32_t len, bool bios)
+{
+	MPI2_FW_DOWNLOAD_REQUEST req;
+	MPI2_FW_DOWNLOAD_REPLY reply;
+
+	bzero(&req, sizeof(req));
+	bzero(&reply, sizeof(reply));
+	req.Function = MPI2_FUNCTION_FW_DOWNLOAD;
+	req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW;
+	req.TotalImageSize = len;
+	req.MsgFlags = MPI2_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
+
+	if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    fw, len, 0)) {
+		return (-1);
+	}
+	return (0);
+}
+
+int
+mps_firmware_get(int fd, unsigned char **firmware, bool bios)
+{
+	MPI2_FW_UPLOAD_REQUEST req;
+	MPI2_FW_UPLOAD_REPLY reply;
+	int size;
+
+	*firmware = NULL;
+	bzero(&req, sizeof(req));
+	bzero(&reply, sizeof(reply));
+	req.Function = MPI2_FUNCTION_FW_UPLOAD;
+	req.ImageType = bios ? MPI2_FW_DOWNLOAD_ITYPE_BIOS : MPI2_FW_DOWNLOAD_ITYPE_FW;
+
+	if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    NULL, 0, 0)) {
+		return (-1);
+	}
+	if (reply.ActualImageSize == 0) {
+		return (-1);
+	}
+
+	size = reply.ActualImageSize;
+	*firmware = calloc(size, sizeof(unsigned char));
+	if (*firmware == NULL) {
+		warn("calloc");
+		return (-1);
+	}
+	if (mps_user_command(fd, &req, sizeof(req), &reply, sizeof(reply),
+	    *firmware, size, 0)) {
+		free(*firmware);
+		return (-1);
+	}
+
+	return (size);
+}
+
+#else
+
+int
+mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
+    MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus)
+{
+	struct mps_cfg_page_req req;
+
+	if (IOCStatus != NULL)
+		*IOCStatus = MPI2_IOCSTATUS_SUCCESS;
+	if (header == NULL)
+		return (EINVAL);
+	bzero(&req, sizeof(req));
+	req.header.PageType = PageType;
+	req.header.PageNumber = PageNumber;
+	req.page_address = PageAddress;
+	if (ioctl(fd, MPSIO_READ_CFG_HEADER, &req) < 0)
+		return (errno);
+	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = req.ioc_status;
+		return (EIO);
+	}
+	bcopy(&req.header, header, sizeof(*header));
+	return (0);
+}
+
+void *
+mps_read_config_page(int fd, U8 PageType, U8 PageNumber, U32 PageAddress,
+    U16 *IOCStatus)
+{
+	struct mps_cfg_page_req req;
+	void *buf;
+	int error;
+
+	error = mps_read_config_page_header(fd, PageType, PageNumber,
+	    PageAddress, &req.header, IOCStatus);
+	if (error) {
+		errno = error;
+		return (NULL);
+	}
+
+	if (req.header.PageLength == 0)
+		req.header.PageLength = 4;
+	req.len = req.header.PageLength * 4;
+	buf = malloc(req.len);
+	req.buf = buf;
+	bcopy(&req.header, buf, sizeof(req.header));
+	if (ioctl(fd, MPSIO_READ_CFG_PAGE, &req) < 0) {
+		error = errno;
+		free(buf);
+		errno = error;
+		return (NULL);
+	}
+	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = req.ioc_status;
+		else
+			warnx("Reading config page failed: 0x%x %s",
+			    req.ioc_status, mps_ioc_status(req.ioc_status));
+		free(buf);
+		errno = EIO;
+		return (NULL);
+	}
+	return (buf);
+}
+
+void *
+mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
+    U8 PageNumber, U32 PageAddress, U16 *IOCStatus)
+{
+	struct mps_ext_cfg_page_req req;
+	void *buf;
+	int error;
+
+	if (IOCStatus != NULL)
+		*IOCStatus = MPI2_IOCSTATUS_SUCCESS;
+	bzero(&req, sizeof(req));
+	req.header.PageVersion = PageVersion;
+	req.header.PageNumber = PageNumber;
+	req.header.ExtPageType = ExtPageType;
+	req.page_address = PageAddress;
+	if (ioctl(fd, MPSIO_READ_EXT_CFG_HEADER, &req) < 0)
+		return (NULL);
+	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = req.ioc_status;
+		else
+			warnx("Reading extended config page header failed: %s",
+			    mps_ioc_status(req.ioc_status));
+		errno = EIO;
+		return (NULL);
+	}
+	req.len = req.header.ExtPageLength * 4;
+	buf = malloc(req.len);
+	req.buf = buf;
+	bcopy(&req.header, buf, sizeof(req.header));
+	if (ioctl(fd, MPSIO_READ_EXT_CFG_PAGE, &req) < 0) {
+		error = errno;
+		free(buf);
+		errno = error;
+		return (NULL);
+	}
+	if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
+		if (IOCStatus != NULL)
+			*IOCStatus = req.ioc_status;
+		else
+			warnx("Reading extended config page failed: %s",
+			    mps_ioc_status(req.ioc_status));
+		free(buf);
+		errno = EIO;
+		return (NULL);
+	}
+	return (buf);
+}
+#endif
+
+int
+mps_open(int unit)
+{
+	char path[MAXPATHLEN];
+
+	snprintf(path, sizeof(path), "/dev/mp%s%d", is_mps ? "s": "r", unit);
+	return (open(path, O_RDWR));
+}
+
+int
+mps_user_command(int fd, void *req, uint32_t req_len, void *reply,
+        uint32_t reply_len, void *buffer, int len, uint32_t flags)
+{
+	struct mps_usr_command cmd;
+
+	bzero(&cmd, sizeof(struct mps_usr_command));
+	cmd.req = req;
+	cmd.req_len = req_len;
+	cmd.rpl = reply;
+	cmd.rpl_len = reply_len;
+	cmd.buf = buffer;
+	cmd.len = len;
+	cmd.flags = flags;
+
+	if (ioctl(fd, is_mps ? MPSIO_MPS_COMMAND : MPRIO_MPR_COMMAND, &cmd) < 0)
+		return (errno);
+	return (0);
+}
+
+int
+mps_pass_command(int fd, void *req, uint32_t req_len, void *reply,
+	uint32_t reply_len, void *data_in, uint32_t datain_len, void *data_out,
+	uint32_t dataout_len, uint32_t timeout)
+{
+	struct mprs_pass_thru pass;
+
+	pass.PtrRequest = (uint64_t)(uintptr_t)req;
+	pass.PtrReply = (uint64_t)(uintptr_t)reply;
+	pass.PtrData = (uint64_t)(uintptr_t)data_in;
+	pass.PtrDataOut = (uint64_t)(uintptr_t)data_out;
+	pass.RequestSize = req_len;
+	pass.ReplySize = reply_len;
+	pass.DataSize = datain_len;
+	pass.DataOutSize = dataout_len;
+	if (datain_len && dataout_len) {
+		if (is_mps) {
+			pass.DataDirection = MPS_PASS_THRU_DIRECTION_BOTH;
+		} else {
+			pass.DataDirection = MPR_PASS_THRU_DIRECTION_BOTH;
+		}
+	} else if (datain_len) {
+		if (is_mps) {
+			pass.DataDirection = MPS_PASS_THRU_DIRECTION_READ;
+		} else {
+			pass.DataDirection = MPR_PASS_THRU_DIRECTION_READ;
+		}
+	} else if (dataout_len) {
+		if (is_mps) {
+			pass.DataDirection = MPS_PASS_THRU_DIRECTION_WRITE;
+		} else {
+			pass.DataDirection = MPR_PASS_THRU_DIRECTION_WRITE;
+		}
+	} else {
+		if (is_mps) {
+			pass.DataDirection = MPS_PASS_THRU_DIRECTION_NONE;
+		} else {
+			pass.DataDirection = MPR_PASS_THRU_DIRECTION_NONE;
+		}
+	}
+	pass.Timeout = timeout;
+
+	if (ioctl(fd, MPTIOCTL_PASS_THRU, &pass) < 0)
+		return (errno);
+	return (0);
+}
+
+MPI2_IOC_FACTS_REPLY *
+mps_get_iocfacts(int fd)
+{
+	MPI2_IOC_FACTS_REPLY *facts;
+	MPI2_IOC_FACTS_REQUEST req;
+	int error;
+
+	facts = malloc(sizeof(MPI2_IOC_FACTS_REPLY));
+	if (facts == NULL) {
+		errno = ENOMEM;
+		return (NULL);
+	}
+
+	bzero(&req, sizeof(MPI2_IOC_FACTS_REQUEST));
+	req.Function = MPI2_FUNCTION_IOC_FACTS;
+
+#if 1
+	error = mps_pass_command(fd, &req, sizeof(MPI2_IOC_FACTS_REQUEST),
+	    facts, sizeof(MPI2_IOC_FACTS_REPLY), NULL, 0, NULL, 0, 10);
+#else
+	error = mps_user_command(fd, &req, sizeof(MPI2_IOC_FACTS_REQUEST),
+	    facts, sizeof(MPI2_IOC_FACTS_REPLY), NULL, 0, 0);
+#endif
+	if (error) {
+		free(facts);
+		return (NULL);
+	}
+
+	if (!IOC_STATUS_SUCCESS(facts->IOCStatus)) {
+		free(facts);
+		errno = EINVAL;
+		return (NULL);
+	}
+	return (facts);
+}
+


Property changes on: trunk/usr.sbin/mpsutil/mps_cmd.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mps_flash.c
===================================================================
--- trunk/usr.sbin/mpsutil/mps_flash.c	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mps_flash.c	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,238 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Baptiste Daroussin <bapt at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$FreeBSD: stable/10/usr.sbin/mpsutil/mps_flash.c 297590 2016-04-05 20:34:20Z sbruno $");
+
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+
+#include <errno.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "mpsutil.h"
+
+MPS_TABLE(top, flash);
+
+static int
+flash_save(int argc, char **argv)
+{
+	const char *firmware_file;
+	unsigned char *firmware_buffer = NULL;
+	int error, fd, size;
+	bool bios = false;
+	ssize_t written = 0, ret = 0;
+
+	if (argc < 2) {
+		warnx("missing argument: expecting 'firmware' or bios'");
+		return (EINVAL);
+	}
+
+	if (strcmp(argv[1], "bios") == 0) {
+		bios = true;
+	} else if (strcmp(argv[1], "firmware") != 0) {
+		warnx("Invalid argument '%s', expecting 'firmware' or 'bios'",
+		    argv[1]);
+	}
+
+	if (argc > 4) {
+		warnx("save %s: extra arguments", argv[1]);
+		return (EINVAL);
+	}
+
+	firmware_file = argv[1];
+	if (argc == 3) {
+		firmware_file = argv[2];
+	}
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	if ((size = mps_firmware_get(fd, &firmware_buffer, bios)) < 0) {
+		warnx("Fail to save %s", argv[1]);
+		return (1);
+	}
+
+	close(fd);
+	if (size > 0) {
+		fd = open(firmware_file, O_CREAT | O_TRUNC | O_RDWR, 0644);
+		if (fd <0) {
+			error = errno;
+			warn("open");
+			free(firmware_buffer);
+			return (error);
+		}
+		while (written != size) {
+			if ((ret = write(fd, firmware_buffer + written, size - written)) <0) {
+				error = errno;
+				warn("write");
+				free(firmware_buffer);
+				return (error);
+			}
+			written += ret;
+		}
+		close(fd);
+	}
+	free(firmware_buffer);
+	printf("%s successfully saved as %s\n", argv[1], firmware_file);
+	return (0);
+}
+
+MPS_COMMAND(flash, save, flash_save, "[firmware|bios] [file]",
+    "Save firmware/bios into a file");
+
+static int
+flash_update(int argc, char **argv)
+{
+	int error, fd;
+	unsigned char *mem = NULL;
+	struct stat st;
+	bool bios = false;
+	MPI2_FW_IMAGE_HEADER *fwheader;
+	MPI2_IOC_FACTS_REPLY *facts;
+
+	if (argc < 2) {
+		warnx("missing argument: expecting 'firmware' or bios'");
+		return (EINVAL);
+	}
+
+	if (strcmp(argv[1], "bios") == 0) {
+		bios = true;
+	} else if (strcmp(argv[1], "firmware") != 0) {
+		warnx("Invalid argument '%s', expecting 'firmware' or 'bios'",
+		    argv[1]);
+	}
+
+	if (argc > 4) {
+		warnx("update firmware: extra arguments");
+		return (EINVAL);
+	}
+
+	if (argc != 3) {
+		warnx("no firmware specified");
+		return (EINVAL);
+	}
+
+	if (stat(argv[2], &st) == -1) {
+		error = errno;
+		warn("stat");
+		return (error);
+	}
+
+	fd = open(argv[2], O_RDONLY);
+	if (fd < 0) {
+		error = errno;
+		warn("open");
+		return (error);
+	}
+
+	mem = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+	if (mem == MAP_FAILED) {
+		error = errno;
+		warn("mmap");
+		close(fd);
+		return (error);
+	}
+	close(fd);
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		munmap(mem, st.st_size);
+		return (error);
+	}
+
+	if ((facts = mps_get_iocfacts(fd)) == NULL) {
+		warnx("could not get controller IOCFacts\n");
+		munmap(mem, st.st_size);
+		close(fd);
+		return (EINVAL);
+	}
+
+	if (bios) {
+		/* Check boot record magic number */
+		if (((mem[0x01]<<8) + mem[0x00]) != 0xaa55) {
+			warnx("Invalid bios: no boot record magic number");
+			munmap(mem, st.st_size);
+			close(fd);
+			return (1);
+		}
+		if ((st.st_size % 512) != 0) {
+			warnx("Invalid bios: size not a multiple of 512");
+			munmap(mem, st.st_size);
+			close(fd);
+			return (1);
+		}
+	} else {
+		fwheader = (MPI2_FW_IMAGE_HEADER *)mem;
+		if (fwheader->VendorID != MPI2_MFGPAGE_VENDORID_LSI) {
+			warnx("Invalid firmware:");
+			warnx("  Expected Vendor ID: %04x",
+			    MPI2_MFGPAGE_VENDORID_LSI);
+			warnx("  Image Vendor ID: %04x", fwheader->VendorID);
+			munmap(mem, st.st_size);
+			close(fd);
+			return (1);
+		}
+
+		if (fwheader->ProductID != facts->ProductID) {
+			warnx("Invalid image:");
+			warnx("  Expected Product ID: %04x", facts->ProductID);
+			warnx("  Image Product ID: %04x", fwheader->ProductID);
+			munmap(mem, st.st_size);
+			close(fd);
+			return (1);
+		}
+	}
+
+	printf("Updating %s...\n", argv[1]);
+	if (mps_firmware_send(fd, mem, st.st_size, bios) < 0) {
+		warnx("Fail to update %s", argv[1]);
+		munmap(mem, st.st_size);
+		close(fd);
+		return (1);
+	}
+
+	munmap(mem, st.st_size);
+	close(fd);
+	printf("%s successfully updated\n", argv[1]);
+	return (0);
+}
+
+MPS_COMMAND(flash, update, flash_update, "[firmware|bios] file",
+    "Update firmware/bios");


Property changes on: trunk/usr.sbin/mpsutil/mps_flash.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mps_ioctl.h
===================================================================
--- trunk/usr.sbin/mpsutil/mps_ioctl.h	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mps_ioctl.h	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,388 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * LSI MPT-Fusion Host Adapter FreeBSD userland interface
+ *
+ * $FreeBSD: stable/10/usr.sbin/mpsutil/mps_ioctl.h 297590 2016-04-05 20:34:20Z sbruno $
+ */
+/*-
+ * Copyright (c) 2011, 2012 LSI Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * LSI MPT-Fusion Host Adapter FreeBSD
+ *
+ * $FreeBSD: stable/10/usr.sbin/mpsutil/mps_ioctl.h 297590 2016-04-05 20:34:20Z sbruno $
+ */
+
+#ifndef _MPS_IOCTL_H_
+#define	_MPS_IOCTL_H_
+
+#include <dev/mps/mpi/mpi2_type.h>
+#include <dev/mps/mpi/mpi2.h>
+#include <dev/mps/mpi/mpi2_cnfg.h>
+#include <dev/mps/mpi/mpi2_sas.h>
+
+/*
+ * For the read header requests, the header should include the page
+ * type or extended page type, page number, and page version.  The
+ * buffer and length are unused.  The completed header is returned in
+ * the 'header' member.
+ *
+ * For the read page and write page requests, 'buf' should point to a
+ * buffer of 'len' bytes which holds the entire page (including the
+ * header).
+ *
+ * All requests specify the page address in 'page_address'.
+ */
+struct mps_cfg_page_req {	
+	MPI2_CONFIG_PAGE_HEADER header;
+	uint32_t page_address;
+	void	*buf;
+	int	len;
+	uint16_t ioc_status;
+};
+
+struct mps_ext_cfg_page_req {
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER header;
+	uint32_t page_address;
+	void	*buf;
+	int	len;
+	uint16_t ioc_status;
+};
+
+struct mps_raid_action {
+	uint8_t action;
+	uint8_t volume_bus;
+	uint8_t volume_id;
+	uint8_t phys_disk_num;
+	uint32_t action_data_word;
+	void *buf;
+	int len;
+	uint32_t volume_status;
+	uint32_t action_data[4];
+	uint16_t action_status;
+	uint16_t ioc_status;
+	uint8_t write;
+};
+
+struct mps_usr_command {
+	void *req;
+	uint32_t req_len;
+	void *rpl;
+	uint32_t rpl_len;
+	void *buf;
+	int len;
+	uint32_t flags;
+};
+
+typedef struct mps_pci_bits
+{
+	union {
+		struct {
+			uint32_t	DeviceNumber	:5;
+			uint32_t	FunctionNumber	:3;
+			uint32_t	BusNumber	:24;
+		} bits;
+		uint32_t	AsDWORD;
+	} u;
+	uint32_t	PciSegmentId;
+} mps_pci_bits_t;
+
+/*
+ *  The following is the MPSIOCTL_GET_ADAPTER_DATA data structure.  This data
+ *  structure is setup so that we hopefully are properly aligned for both
+ *  32-bit and 64-bit mode applications.
+ *
+ *  Adapter Type - Value = 4 = SCSI Protocol through SAS-2 adapter
+ *
+ *  MPI Port Number - The PCI Function number for this device
+ *
+ *  PCI Device HW Id - The PCI device number for this device
+ *
+ */
+#define	MPSIOCTL_ADAPTER_TYPE_SAS2		4
+#define	MPSIOCTL_ADAPTER_TYPE_SAS2_SSS6200	5
+typedef struct mps_adapter_data
+{
+	uint32_t	StructureLength;
+	uint32_t	AdapterType;
+	uint32_t	MpiPortNumber;
+	uint32_t	PCIDeviceHwId;
+	uint32_t	PCIDeviceHwRev;
+	uint32_t	SubSystemId;
+	uint32_t	SubsystemVendorId;
+	uint32_t	Reserved1;
+	uint32_t	MpiFirmwareVersion;
+	uint32_t	BiosVersion;
+	uint8_t		DriverVersion[32];
+	uint8_t		Reserved2;
+	uint8_t		ScsiId;
+	uint16_t	Reserved3;
+	mps_pci_bits_t	PciInformation;
+} mps_adapter_data_t;
+
+
+typedef struct mps_update_flash
+{
+	uint64_t	PtrBuffer;
+	uint32_t	ImageChecksum;
+	uint32_t	ImageOffset;
+	uint32_t	ImageSize;
+	uint32_t	ImageType;
+} mps_update_flash_t;
+
+
+#define	MPS_PASS_THRU_DIRECTION_NONE	0
+#define	MPS_PASS_THRU_DIRECTION_READ	1
+#define	MPS_PASS_THRU_DIRECTION_WRITE	2
+#define	MPS_PASS_THRU_DIRECTION_BOTH	3
+
+typedef struct mps_pass_thru
+{
+	uint64_t	PtrRequest;
+	uint64_t	PtrReply;
+	uint64_t	PtrData;
+	uint32_t	RequestSize;
+	uint32_t	ReplySize;
+	uint32_t	DataSize;
+	uint32_t	DataDirection;
+	uint64_t	PtrDataOut;
+	uint32_t	DataOutSize;
+	uint32_t	Timeout;
+} mps_pass_thru_t;
+
+
+/*
+ * Event queue defines
+ */
+#define	MPS_EVENT_QUEUE_SIZE		(50) /* Max Events stored in driver */
+#define	MPS_MAX_EVENT_DATA_LENGTH	(48) /* Size of each event in Dwords */
+
+typedef struct mps_event_query
+{
+	uint16_t	Entries;
+	uint16_t	Reserved;
+	uint32_t	Types[4];
+} mps_event_query_t;
+
+typedef struct mps_event_enable
+{
+	uint32_t	Types[4];
+} mps_event_enable_t;
+
+/*
+ * Event record entry for ioctl.
+ */
+typedef struct mps_event_entry
+{
+	uint32_t	Type;
+	uint32_t	Number;
+	uint32_t	Data[MPS_MAX_EVENT_DATA_LENGTH];
+} mps_event_entry_t;
+
+typedef struct mps_event_report
+{
+	uint32_t	Size;
+	uint64_t	PtrEvents;
+} mps_event_report_t;
+
+
+typedef struct mps_pci_info
+{
+	uint32_t	BusNumber;
+	uint8_t		DeviceNumber;
+	uint8_t		FunctionNumber;
+	uint16_t	InterruptVector;
+	uint8_t		PciHeader[256];
+} mps_pci_info_t;
+
+
+typedef struct mps_diag_action
+{
+	uint32_t	Action;
+	uint32_t	Length;
+	uint64_t	PtrDiagAction;
+	uint32_t	ReturnCode;
+} mps_diag_action_t;
+
+#define	MPS_FW_DIAGNOSTIC_UID_NOT_FOUND	(0xFF)
+
+#define	MPS_FW_DIAG_NEW				(0x806E6577)
+
+#define	MPS_FW_DIAG_TYPE_REGISTER		(0x00000001)
+#define	MPS_FW_DIAG_TYPE_UNREGISTER		(0x00000002)
+#define	MPS_FW_DIAG_TYPE_QUERY			(0x00000003)
+#define	MPS_FW_DIAG_TYPE_READ_BUFFER		(0x00000004)
+#define	MPS_FW_DIAG_TYPE_RELEASE		(0x00000005)
+
+#define	MPS_FW_DIAG_INVALID_UID			(0x00000000)
+
+#define MPS_DIAG_SUCCESS			0
+#define MPS_DIAG_FAILURE			1
+
+#define	MPS_FW_DIAG_ERROR_SUCCESS		(0x00000000)
+#define	MPS_FW_DIAG_ERROR_FAILURE		(0x00000001)
+#define	MPS_FW_DIAG_ERROR_INVALID_PARAMETER	(0x00000002)
+#define	MPS_FW_DIAG_ERROR_POST_FAILED		(0x00000010)
+#define	MPS_FW_DIAG_ERROR_INVALID_UID		(0x00000011)
+#define	MPS_FW_DIAG_ERROR_RELEASE_FAILED	(0x00000012)
+#define	MPS_FW_DIAG_ERROR_NO_BUFFER		(0x00000013)
+#define	MPS_FW_DIAG_ERROR_ALREADY_RELEASED	(0x00000014)
+
+
+typedef struct mps_fw_diag_register
+{
+	uint8_t		ExtendedType;
+	uint8_t		BufferType;
+	uint16_t	ApplicationFlags;
+	uint32_t	DiagnosticFlags;
+	uint32_t	ProductSpecific[23];
+	uint32_t	RequestedBufferSize;
+	uint32_t	UniqueId;
+} mps_fw_diag_register_t;
+
+typedef struct mps_fw_diag_unregister
+{
+	uint32_t	UniqueId;
+} mps_fw_diag_unregister_t;
+
+#define	MPS_FW_DIAG_FLAG_APP_OWNED		(0x0001)
+#define	MPS_FW_DIAG_FLAG_BUFFER_VALID		(0x0002)
+#define	MPS_FW_DIAG_FLAG_FW_BUFFER_ACCESS	(0x0004)
+
+typedef struct mps_fw_diag_query
+{
+	uint8_t		ExtendedType;
+	uint8_t		BufferType;
+	uint16_t	ApplicationFlags;
+	uint32_t	DiagnosticFlags;
+	uint32_t	ProductSpecific[23];
+	uint32_t	TotalBufferSize;
+	uint32_t	DriverAddedBufferSize;
+	uint32_t	UniqueId;
+} mps_fw_diag_query_t;
+
+typedef struct mps_fw_diag_release
+{
+	uint32_t	UniqueId;
+} mps_fw_diag_release_t;
+
+#define	MPS_FW_DIAG_FLAG_REREGISTER	(0x0001)
+#define	MPS_FW_DIAG_FLAG_FORCE_RELEASE	(0x0002)
+
+typedef struct mps_diag_read_buffer
+{
+	uint8_t		Status;
+	uint8_t		Reserved;
+	uint16_t	Flags;
+	uint32_t	StartingOffset;
+	uint32_t	BytesToRead;
+	uint32_t	UniqueId;
+	uint64_t	PtrDataBuffer;
+} mps_diag_read_buffer_t;
+
+/*
+ * Register Access
+ */
+#define	REG_IO_READ	1
+#define	REG_IO_WRITE	2
+#define	REG_MEM_READ	3
+#define	REG_MEM_WRITE	4
+
+typedef struct mps_reg_access
+{
+	uint32_t	Command;
+	uint32_t	RegOffset;
+	uint32_t	RegData;
+} mps_reg_access_t;
+
+typedef struct mps_btdh_mapping
+{
+	uint16_t	TargetID;
+	uint16_t	Bus;
+	uint16_t	DevHandle;
+	uint16_t	Reserved;
+} mps_btdh_mapping_t;
+
+#define MPSIO_MPS_COMMAND_FLAG_VERBOSE	0x01
+#define MPSIO_MPS_COMMAND_FLAG_DEBUG	0x02
+#define	MPSIO_READ_CFG_HEADER	_IOWR('M', 200, struct mps_cfg_page_req)
+#define	MPSIO_READ_CFG_PAGE	_IOWR('M', 201, struct mps_cfg_page_req)
+#define	MPSIO_READ_EXT_CFG_HEADER _IOWR('M', 202, struct mps_ext_cfg_page_req)
+#define	MPSIO_READ_EXT_CFG_PAGE	_IOWR('M', 203, struct mps_ext_cfg_page_req)
+#define	MPSIO_WRITE_CFG_PAGE	_IOWR('M', 204, struct mps_cfg_page_req)
+#define	MPSIO_RAID_ACTION	_IOWR('M', 205, struct mps_raid_action)
+#define	MPSIO_MPS_COMMAND	_IOWR('M', 210, struct mps_usr_command)
+
+#define	MPTIOCTL			('I')
+#define	MPTIOCTL_GET_ADAPTER_DATA	_IOWR(MPTIOCTL, 1,\
+    struct mps_adapter_data)
+#define	MPTIOCTL_UPDATE_FLASH		_IOWR(MPTIOCTL, 2,\
+    struct mps_update_flash)
+#define	MPTIOCTL_RESET_ADAPTER		_IO(MPTIOCTL, 3)
+#define	MPTIOCTL_PASS_THRU		_IOWR(MPTIOCTL, 4,\
+    struct mps_pass_thru)
+#define	MPTIOCTL_EVENT_QUERY		_IOWR(MPTIOCTL, 5,\
+    struct mps_event_query)
+#define	MPTIOCTL_EVENT_ENABLE		_IOWR(MPTIOCTL, 6,\
+    struct mps_event_enable)
+#define	MPTIOCTL_EVENT_REPORT		_IOWR(MPTIOCTL, 7,\
+    struct mps_event_report)
+#define	MPTIOCTL_GET_PCI_INFO		_IOWR(MPTIOCTL, 8,\
+    struct mps_pci_info)
+#define	MPTIOCTL_DIAG_ACTION		_IOWR(MPTIOCTL, 9,\
+    struct mps_diag_action)
+#define	MPTIOCTL_REG_ACCESS		_IOWR(MPTIOCTL, 10,\
+    struct mps_reg_access)
+#define	MPTIOCTL_BTDH_MAPPING		_IOWR(MPTIOCTL, 11,\
+    struct mps_btdh_mapping)
+
+#endif /* !_MPS_IOCTL_H_ */


Property changes on: trunk/usr.sbin/mpsutil/mps_ioctl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mps_show.c
===================================================================
--- trunk/usr.sbin/mpsutil/mps_show.c	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mps_show.c	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,773 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Netflix, Inc.
+ * All rights reserved.
+ * Written by: Scott Long <scottl at freebsd.org>
+ *
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$FreeBSD: stable/10/usr.sbin/mpsutil/mps_show.c 297590 2016-04-05 20:34:20Z sbruno $");
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <err.h>
+#include <libutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "mpsutil.h"
+
+static char * get_device_speed(uint8_t rate);
+static char * get_device_type(uint32_t di);
+static int show_all(int ac, char **av);
+static int show_devices(int ac, char **av);
+static int show_enclosures(int ac, char **av);
+static int show_expanders(int ac, char **av);
+
+MPS_TABLE(top, show);
+
+#define	STANDALONE_STATE	"ONLINE"
+
+static int
+show_adapter(int ac, char **av)
+{
+	MPI2_CONFIG_PAGE_SASIOUNIT_0	*sas0;
+	MPI2_CONFIG_PAGE_SASIOUNIT_1	*sas1;
+	MPI2_SAS_IO_UNIT0_PHY_DATA	*phy0;
+	MPI2_SAS_IO_UNIT1_PHY_DATA	*phy1;
+	MPI2_CONFIG_PAGE_MAN_0 *man0;
+	MPI2_CONFIG_PAGE_BIOS_3 *bios3;
+	MPI2_IOC_FACTS_REPLY *facts;
+	U16 IOCStatus;
+	char *speed, *minspeed, *maxspeed, *isdisabled, *type;
+	char devhandle[5], ctrlhandle[5];
+	int error, fd, v, i;
+
+	if (ac != 1) {
+		warnx("show adapter: extra arguments");
+		return (EINVAL);
+	}
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	man0 = mps_read_man_page(fd, 0, NULL);
+	if (man0 == NULL) {
+		error = errno;
+		warn("Failed to get controller info");
+		return (error);
+	}
+	if (man0->Header.PageLength < sizeof(*man0) / 4) {
+		warnx("Invalid controller info");
+		return (EINVAL);
+	}
+	printf("mp%s%d Adapter:\n", is_mps ? "s": "r", mps_unit);
+	printf("       Board Name: %.16s\n", man0->BoardName);
+	printf("   Board Assembly: %.16s\n", man0->BoardAssembly);
+	printf("        Chip Name: %.16s\n", man0->ChipName);
+	printf("    Chip Revision: %.16s\n", man0->ChipRevision);
+	free(man0);
+
+	bios3 = mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_BIOS, 3, 0, NULL);
+	if (bios3 == NULL) {
+		error = errno;
+		warn("Failed to get BIOS page 3 info");
+		return (error);
+	}
+	v = bios3->BiosVersion;
+	printf("    BIOS Revision: %d.%02d.%02d.%02d\n",
+	    ((v & 0xff000000) >> 24), ((v &0xff0000) >> 16),
+	    ((v & 0xff00) >> 8), (v & 0xff));
+	free(bios3);
+
+	if ((facts = mps_get_iocfacts(fd)) == NULL) {
+		printf("could not get controller IOCFacts\n");
+		close(fd);
+		return (errno);
+	}
+	v = facts->FWVersion.Word;
+	printf("Firmware Revision: %d.%02d.%02d.%02d\n",
+	    ((v & 0xff000000) >> 24), ((v &0xff0000) >> 16),
+	    ((v & 0xff00) >> 8), (v & 0xff));
+	printf("  Integrated RAID: %s\n",
+	    (facts->IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID)
+	    ? "yes" : "no");
+	free(facts);
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	sas0 = mps_read_extended_config_page(fd,
+	    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
+	    MPI2_SASIOUNITPAGE0_PAGEVERSION, 0, 0, &IOCStatus);
+	if (sas0 == NULL) {
+		error = errno;
+		warn("Error retrieving SAS IO Unit page %d", IOCStatus);
+		return (error);
+	}
+
+	sas1 = mps_read_extended_config_page(fd,
+	    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
+	    MPI2_SASIOUNITPAGE1_PAGEVERSION, 1, 0, &IOCStatus);
+	if (sas0 == NULL) {
+		error = errno;
+		warn("Error retrieving SAS IO Unit page %d", IOCStatus);
+		return (error);
+	}
+	printf("\n");
+
+	printf("%-8s%-12s%-11s%-10s%-8s%-7s%-7s%s\n", "PhyNum", "CtlrHandle",
+	    "DevHandle", "Disabled", "Speed", "Min", "Max", "Device");
+	for (i = 0; i < sas0->NumPhys; i++) {
+		phy0 = &sas0->PhyData[i];
+		phy1 = &sas1->PhyData[i];
+		if (phy0->PortFlags &
+		     MPI2_SASIOUNIT0_PORTFLAGS_DISCOVERY_IN_PROGRESS) {
+			printf("Discovery still in progress\n");
+			continue;
+		}
+		if (phy0->PhyFlags & MPI2_SASIOUNIT0_PHYFLAGS_PHY_DISABLED)
+			isdisabled = "Y";
+		else
+			isdisabled = "N";
+
+		minspeed = get_device_speed(phy1->MaxMinLinkRate);
+		maxspeed = get_device_speed(phy1->MaxMinLinkRate >> 4);
+		type = get_device_type(phy0->ControllerPhyDeviceInfo);
+
+		if (phy0->AttachedDevHandle != 0) {
+			snprintf(devhandle, 5, "%04x", phy0->AttachedDevHandle);
+			snprintf(ctrlhandle, 5, "%04x",
+			    phy0->ControllerDevHandle);
+			speed = get_device_speed(phy0->NegotiatedLinkRate);
+		} else {
+			snprintf(devhandle, 5, "    ");
+			snprintf(ctrlhandle, 5, "    ");
+			speed = "     ";
+		}
+		printf("%-8d%-12s%-11s%-10s%-8s%-7s%-7s%s\n",
+		    i, ctrlhandle, devhandle, isdisabled, speed, minspeed,
+		    maxspeed, type);
+	}
+	free(sas0);
+	free(sas1);
+	printf("\n");
+	close(fd);
+	return (0);
+}
+
+MPS_COMMAND(show, adapter, show_adapter, "", "display controller information")
+
+static int
+show_iocfacts(int ac, char **av)
+{
+	MPI2_IOC_FACTS_REPLY *facts;
+	int error, fd;
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	if ((facts = mps_get_iocfacts(fd)) == NULL) {
+		printf("could not get controller IOCFacts\n");
+		close(fd);
+		return (errno);
+	}
+
+	printf("       MaxChainDepth: %d\n", facts->MaxChainDepth);
+	printf("             WhoInit: 0x%x\n", facts->WhoInit);
+	printf("       NumberOfPorts: %d\n", facts->NumberOfPorts);
+	printf("      MaxMSIxVectors: %d\n", facts->MaxMSIxVectors);
+	printf("       RequestCredit: %d\n", facts->RequestCredit);
+	printf("           ProductID: 0x%x\n", facts->ProductID);
+	printf("     IOCCapabilities: 0x%x\n", facts->IOCCapabilities);
+	printf("           FWVersion: 0x%08x\n", facts->FWVersion.Word);
+	printf(" IOCRequestFrameSize: %d\n", facts->IOCRequestFrameSize);
+	printf("       MaxInitiators: %d\n", facts->MaxInitiators);
+	printf("          MaxTargets: %d\n", facts->MaxTargets);
+	printf("     MaxSasExpanders: %d\n", facts->MaxSasExpanders);
+	printf("       MaxEnclosures: %d\n", facts->MaxEnclosures);
+	printf("       ProtocolFlags: 0x%x\n", facts->ProtocolFlags);
+	printf("  HighPriorityCredit: %d\n", facts->HighPriorityCredit);
+	printf("MaxRepDescPostQDepth: %d\n",
+	    facts->MaxReplyDescriptorPostQueueDepth);
+	printf("      ReplyFrameSize: %d\n", facts->ReplyFrameSize);
+	printf("          MaxVolumes: %d\n", facts->MaxVolumes);
+	printf("        MaxDevHandle: %d\n", facts->MaxDevHandle);
+	printf("MaxPersistentEntries: %d\n", facts->MaxPersistentEntries);
+	printf("        MinDevHandle: %d\n", facts->MinDevHandle);
+
+	free(facts);
+	return (0);
+}
+
+MPS_COMMAND(show, iocfacts, show_iocfacts, "", "Show IOC Facts Message");
+
+static int
+show_adapters(int ac, char **av)
+{
+	MPI2_CONFIG_PAGE_MAN_0 *man0;
+	MPI2_IOC_FACTS_REPLY *facts;
+	int unit, fd, error;
+
+	printf("Device Name\t      Chip Name        Board Name        Firmware\n");
+	for (unit = 0; unit < MPS_MAX_UNIT; unit++) {
+		fd = mps_open(unit);
+		if (fd < 0)
+			continue;
+		facts = mps_get_iocfacts(fd);
+		if (facts == NULL) {
+			error = errno;
+			warn("Faled to get controller iocfacts");
+			close(fd);
+			return (error);
+		}
+		man0 = mps_read_man_page(fd, 0, NULL);
+		if (man0 == NULL) {
+			error = errno;
+			warn("Failed to get controller info");
+			close(fd);
+			return (error);
+		}
+		if (man0->Header.PageLength < sizeof(*man0) / 4) {
+			warnx("Invalid controller info");
+			close(fd);
+			free(man0);
+			return (EINVAL);
+		}
+		printf("/dev/mp%s%d\t%16s %16s        %08x\n",
+		    is_mps ? "s": "r", unit,
+		    man0->ChipName, man0->BoardName, facts->FWVersion.Word);
+		free(man0);
+		free(facts);
+		close(fd);
+	}
+	return (0);
+}
+MPS_COMMAND(show, adapters, show_adapters, "", "Show a summary of all adapters");
+
+static char *
+get_device_type(uint32_t di)
+{
+
+	if (di & 0x4000)
+		return ("SEP Target    ");
+	if (di & 0x2000)
+		return ("ATAPI Target  ");
+	if (di & 0x400)
+		return ("SAS Target    ");
+	if (di & 0x200)
+		return ("STP Target    ");
+	if (di & 0x100)
+		return ("SMP Target    ");
+	if (di & 0x80)
+		return ("SATA Target   ");
+	if (di & 0x70)
+		return ("SAS Initiator ");
+	if (di & 0x8)
+		return ("SATA Initiator");
+	if ((di & 0x7) == 0)
+		return ("No Device     ");
+	return ("Unknown Device");
+}
+
+static char *
+get_enc_type(uint32_t flags, int *issep)
+{
+	char *type;
+
+	*issep = 0;
+	switch (flags & 0xf) {
+	case 0x01:
+		type = "Direct Attached SES-2";
+		*issep = 1;
+		break;
+	case 0x02:
+		type = "Direct Attached SGPIO";
+		break;
+	case 0x03:
+		type = "Expander SGPIO";
+		break;
+	case 0x04:
+		type = "External SES-2";
+		*issep = 1;
+		break;
+	case 0x05:
+		type = "Direct Attached GPIO";
+		break;
+	case 0x0:
+	default:
+		return ("Unknown");
+	}
+
+	return (type);
+}
+
+static char *
+mps_device_speed[] = {
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"1.5",
+	"3.0",
+	"6.0",
+	"12 "
+};
+
+static char *
+get_device_speed(uint8_t rate)
+{
+	char *speed;
+
+	rate &= 0xf;
+	if (rate >= sizeof(mps_device_speed))
+		return ("Unk");
+
+	if ((speed = mps_device_speed[rate]) == NULL)
+		return ("???");
+	return (speed);
+}
+
+static char *
+mps_page_name[] = {
+	"IO Unit",
+	"IOC",
+	"BIOS",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"RAID Volume",
+	"Manufacturing",
+	"RAID Physical Disk",
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	"SAS IO Unit",
+	"SAS Expander",
+	"SAS Device",
+	"SAS PHY",
+	"Log",
+	"Enclosure",
+	"RAID Configuration",
+	"Driver Persistent Mapping",
+	"SAS Port",
+	"Ethernet Port",
+	"Extended Manufacturing"
+};
+
+static char *
+get_page_name(u_int page)
+{
+	char *name;
+
+	if (page >= sizeof(mps_page_name))
+		return ("Unknown");
+	if ((name = mps_page_name[page]) == NULL)
+		return ("Unknown");
+	return (name);
+}
+
+static int
+show_all(int ac, char **av)
+{
+	int error;
+
+	printf("Adapter:\n");
+	error = show_adapter(ac, av);
+	printf("Devices:\n");
+	error = show_devices(ac, av);
+	printf("Enclosures:\n");
+	error = show_enclosures(ac, av);
+	printf("Expanders:\n");
+	error = show_expanders(ac, av);
+	return (error);
+}
+MPS_COMMAND(show, all, show_all, "", "Show all devices");
+
+static int
+show_devices(int ac, char **av)
+{
+	MPI2_CONFIG_PAGE_SASIOUNIT_0	*sas0;
+	MPI2_SAS_IO_UNIT0_PHY_DATA	*phydata;
+	MPI2_CONFIG_PAGE_SAS_DEV_0	*device;
+	MPI2_CONFIG_PAGE_EXPANDER_1	*exp1;
+	uint16_t IOCStatus, handle, bus, target;
+	char *type, *speed, enchandle[5], slot[3], bt[8];
+	char buf[256];
+	int fd, error, nphys;
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	sas0 = mps_read_extended_config_page(fd,
+	    MPI2_CONFIG_EXTPAGETYPE_SAS_IO_UNIT,
+	    MPI2_SASIOUNITPAGE0_PAGEVERSION, 0, 0, &IOCStatus);
+	if (sas0 == NULL) {
+		error = errno;
+		warn("Error retrieving SAS IO Unit page %d", IOCStatus);
+		return (error);
+	}
+	nphys = sas0->NumPhys;
+
+	printf("B____%-5s%-17s%-8s%-10s%-14s%-6s%-5s%-6s%s\n",
+	    "T", "SAS Address", "Handle", "Parent", "Device", "Speed",
+	    "Enc", "Slot", "Wdt");
+	handle = 0xffff;
+	while (1) {
+		device = mps_read_extended_config_page(fd,
+		    MPI2_CONFIG_EXTPAGETYPE_SAS_DEVICE,
+		    MPI2_SASDEVICE0_PAGEVERSION, 0,
+		    MPI2_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE | handle,
+		    &IOCStatus);
+		if (device == NULL) {
+			if (IOCStatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+				break;
+			error = errno;
+			warn("Error retrieving device page");
+			return (error);
+		}
+		handle = device->DevHandle;
+
+		if (device->ParentDevHandle == 0x0) {
+			free(device);
+			continue;
+		}
+
+		bus = 0xffff;
+		target = 0xffff;
+		error = mps_map_btdh(fd, &handle, &bus, &target);
+		if (error) {
+			free(device);
+			continue;
+		}
+		if ((bus == 0xffff) || (target == 0xffff))
+			snprintf(bt, sizeof(bt), "       ");
+		else
+			snprintf(bt, sizeof(bt), "%02d   %02d", bus, target);
+
+		type = get_device_type(device->DeviceInfo);
+
+		if (device->PhyNum < nphys) {
+			phydata = &sas0->PhyData[device->PhyNum];
+			speed = get_device_speed(phydata->NegotiatedLinkRate);
+		} else if (device->ParentDevHandle > 0) {
+			exp1 = mps_read_extended_config_page(fd,
+			    MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER,
+			    MPI2_SASEXPANDER1_PAGEVERSION, 1,
+			    MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
+			    (device->PhyNum <<
+			    MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
+			    device->ParentDevHandle, &IOCStatus);
+			if (exp1 == NULL) {
+				if (IOCStatus != MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) {
+					error = errno;
+					warn("Error retrieving expander page 1: 0x%x",
+					    IOCStatus);
+					return (error);
+				}
+				speed = " ";
+			} else {
+				speed = get_device_speed(exp1->NegotiatedLinkRate);
+				free(exp1);
+			}
+		} else
+			speed = " ";
+
+		if (device->EnclosureHandle != 0) {
+			snprintf(enchandle, 5, "%04x", device->EnclosureHandle);
+			snprintf(slot, 3, "%02d", device->Slot);
+		} else {
+			snprintf(enchandle, 5, "    ");
+			snprintf(slot, 3, "  ");
+		}
+		printf("%-10s", bt);
+		snprintf(buf, sizeof(buf), "%08x%08x", device->SASAddress.High,
+		    device->SASAddress.Low);
+		printf("%-17s", buf);
+		snprintf(buf, sizeof(buf), "%04x", device->DevHandle);
+		printf("%-8s", buf);
+		snprintf(buf, sizeof(buf), "%04x", device->ParentDevHandle);
+		printf("%-10s", buf);
+		printf("%-14s%-6s%-5s%-6s%d\n", type, speed,
+		    enchandle, slot, device->MaxPortConnections);
+		free(device);
+	}
+	printf("\n");
+	free(sas0);
+	close(fd);
+	return (0);
+}
+MPS_COMMAND(show, devices, show_devices, "", "Show attached devices");
+
+static int
+show_enclosures(int ac, char **av)
+{
+	MPI2_CONFIG_PAGE_SAS_ENCLOSURE_0 *enc;
+	char *type, sepstr[5];
+	uint16_t IOCStatus, handle;
+	int fd, error, issep;
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	printf("Slots      Logical ID     SEPHandle  EncHandle    Type\n");
+	handle = 0xffff;
+	while (1) {
+		enc = mps_read_extended_config_page(fd,
+		    MPI2_CONFIG_EXTPAGETYPE_ENCLOSURE,
+		    MPI2_SASENCLOSURE0_PAGEVERSION, 0,
+		    MPI2_SAS_ENCLOS_PGAD_FORM_GET_NEXT_HANDLE | handle,
+		    &IOCStatus);
+		if (enc == NULL) {
+			if (IOCStatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+				break;
+			error = errno;
+			warn("Error retrieving enclosure page");
+			return (error);
+		}
+		type = get_enc_type(enc->Flags, &issep);
+		if (issep == 0)
+			snprintf(sepstr, 5, "    ");
+		else
+			snprintf(sepstr, 5, "%04x", enc->SEPDevHandle);
+		printf("  %.2d    %08x%08x    %s       %04x     %s\n",
+		    enc->NumSlots, enc->EnclosureLogicalID.High,
+		    enc->EnclosureLogicalID.Low, sepstr, enc->EnclosureHandle,
+		    type);
+		handle = enc->EnclosureHandle;
+		free(enc);
+	}
+	printf("\n");
+	close(fd);
+	return (0);
+}
+MPS_COMMAND(show, enclosures, show_enclosures, "", "Show attached enclosures");
+
+static int
+show_expanders(int ac, char **av)
+{
+	MPI2_CONFIG_PAGE_EXPANDER_0	*exp0;
+	MPI2_CONFIG_PAGE_EXPANDER_1	*exp1;
+	uint16_t IOCStatus, handle;
+	char enchandle[5], parent[5], rphy[3], rhandle[5];
+	char *speed, *min, *max, *type;
+	int fd, error, nphys, i;
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	printf("NumPhys   SAS Address     DevHandle   Parent  EncHandle  SAS Level\n");
+	handle = 0xffff;
+	while (1) {
+		exp0 = mps_read_extended_config_page(fd,
+		    MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER,
+		    MPI2_SASEXPANDER0_PAGEVERSION, 0,
+		    MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL | handle,
+		    &IOCStatus);
+		if (exp0 == NULL) {
+			if (IOCStatus == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+				break;
+			error = errno;
+			warn("Error retrieving expander page 0");
+			return (error);
+		}
+
+		nphys = exp0->NumPhys;
+		handle = exp0->DevHandle;
+
+		if (exp0->EnclosureHandle == 0x00)
+			snprintf(enchandle, 5, "    ");
+		else
+			snprintf(enchandle, 5, "%04d", exp0->EnclosureHandle);
+		if (exp0->ParentDevHandle == 0x0)
+			snprintf(parent, 5, "    ");
+		else
+			snprintf(parent, 5, "%04x", exp0->ParentDevHandle);
+		printf("  %02d    %08x%08x    %04x       %s     %s       %d\n",
+		    exp0->NumPhys, exp0->SASAddress.High, exp0->SASAddress.Low,
+		    exp0->DevHandle, parent, enchandle, exp0->SASLevel);
+
+		printf("\n");
+		printf("     Phy  RemotePhy  DevHandle  Speed   Min    Max    Device\n");
+		for (i = 0; i < nphys; i++) {
+			exp1 = mps_read_extended_config_page(fd,
+			    MPI2_CONFIG_EXTPAGETYPE_SAS_EXPANDER,
+			    MPI2_SASEXPANDER1_PAGEVERSION, 1,
+			    MPI2_SAS_EXPAND_PGAD_FORM_HNDL_PHY_NUM |
+			    (i << MPI2_SAS_EXPAND_PGAD_PHYNUM_SHIFT) |
+			    exp0->DevHandle, &IOCStatus);
+			if (exp1 == NULL) {
+				if (IOCStatus !=
+				    MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+					warn("Error retrieving expander pg 1");
+				continue;
+			}
+			type = get_device_type(exp1->AttachedDeviceInfo);
+			if ((exp1->AttachedDeviceInfo &0x7) == 0) {
+				speed = "     ";
+				snprintf(rphy, 3, "  ");
+				snprintf(rhandle, 5, "     ");
+			} else {
+				speed = get_device_speed(
+				    exp1->NegotiatedLinkRate);
+				snprintf(rphy, 3, "%02d",
+				    exp1->AttachedPhyIdentifier);
+				snprintf(rhandle, 5, "%04x",
+				    exp1->AttachedDevHandle);
+			}
+			min = get_device_speed(exp1->HwLinkRate);
+			max = get_device_speed(exp1->HwLinkRate >> 4);
+			printf("     %02d     %s         %s     %s  %s  %s  %s\n", exp1->Phy, rphy, rhandle, speed, min, max, type);
+
+			free(exp1);
+		}
+		free(exp0);
+	}
+
+	printf("\n");
+	close(fd);
+	return (0);
+}
+
+MPS_COMMAND(show, expanders, show_expanders, "", "Show attached expanders");
+
+static int
+show_cfgpage(int ac, char **av)
+{
+	MPI2_CONFIG_PAGE_HEADER *hdr;
+	MPI2_CONFIG_EXTENDED_PAGE_HEADER *ehdr;
+	void *data;
+	uint32_t addr;
+	uint16_t IOCStatus;
+	uint8_t page, num;
+	int fd, error, len, attrs;
+	char *pgname, *pgattr;
+
+	fd = mps_open(mps_unit);
+	if (fd < 0) {
+		error = errno;
+		warn("mps_open");
+		return (error);
+	}
+
+	addr = 0;
+	num = 0;
+	page = 0;
+
+	switch (ac) {
+	case 4:
+		addr = (uint32_t)strtoul(av[3], NULL, 0);
+	case 3:
+		num = (uint8_t)strtoul(av[2], NULL, 0);
+	case 2:
+		page = (uint8_t)strtoul(av[1], NULL, 0);
+		break;
+	default:
+		errno = EINVAL;
+		warn("cfgpage: not enough arguments");
+		return (EINVAL);
+	}
+
+	if (page >= 0x10)
+		data = mps_read_extended_config_page(fd, page, 0, num, addr,
+		    &IOCStatus);
+	 else 
+		data = mps_read_config_page(fd, page, num, addr, &IOCStatus);
+
+	if (data == NULL) {
+		error = errno;
+		warn("Error retrieving cfg page: %s\n",
+		    mps_ioc_status(IOCStatus));
+		return (error);
+	}
+
+	if (page >= 0x10) {
+		ehdr = data;
+		len = ehdr->ExtPageLength * 4;
+		page = ehdr->ExtPageType;
+		attrs = ehdr->PageType >> 4;
+	} else {
+		hdr = data;
+		len = hdr->PageLength * 4;
+		page = hdr->PageType & 0xf;
+		attrs = hdr->PageType >> 4;
+	}
+
+	pgname = get_page_name(page);
+	if (attrs == 0)
+		pgattr = "Read-only";
+	else if (attrs == 1)
+		pgattr = "Read-Write";
+	else if (attrs == 2)
+		pgattr = "Read-Write Persistent";
+	else
+		pgattr = "Unknown Page Attribute";
+
+	printf("Page 0x%x: %s %d, %s\n", page, pgname, num, pgattr);
+	hexdump(data, len, NULL, HD_REVERSED | 4);
+	free(data);
+	return (0);
+}
+
+MPS_COMMAND(show, cfgpage, show_cfgpage, "page [num] [addr]", "Display config page");


Property changes on: trunk/usr.sbin/mpsutil/mps_show.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mpsutil.8
===================================================================
--- trunk/usr.sbin/mpsutil/mpsutil.8	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mpsutil.8	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,166 @@
+.\" $MidnightBSD$
+.\"
+.\" Copyright (c) Baptiste Daroussin <bapt at FreeBSD.org>
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: stable/10/usr.sbin/mpsutil/mpsutil.8 297590 2016-04-05 20:34:20Z sbruno $
+.\"
+.Dd November 17, 2015
+.Dt MPSUTIL 8
+.Os
+.Sh NAME
+.Nm mpsutil ,
+.Nm mprutil
+.Nd Utility for managing LSI Fusion-MPT 2/3 controllers
+.Sh SYNOPSIS
+.Nm
+.Cm version
+.Nm
+.Op Fl u Ar unit
+.Cm show adapter
+.Nm
+.Op Fl u Ar unit
+.Cm show adapters
+.Nm
+.Op Fl u Ar unit
+.Cm show all
+.Nm
+.Op Fl u Ar unit
+.Cm show cfgpages page
+.Op Ar num
+.Op Ar addr
+.Nm
+.Op Fl u Ar unit
+.Cm show devices
+.Nm
+.Op Fl u Ar unit
+.Cm show enclosures
+.Nm
+.Op Fl u Ar unit
+.Cm show expanders
+.Nm
+.Op Fl u Ar unit
+.Cm show iocfacts
+.Nm
+.Op Fl u Ar unit
+.Cm flash save
+.Op Ar firmware Ns | Ns Ar bios
+.Op Ar file
+.Nm
+.Op Fl u Ar unit
+.Cm flash update
+.Op Ar firmware Ns | Ns Ar bios
+.Ar file
+.Sh DESCRIPTION
+The
+.Nm
+utility can be used to display or modify various parameters on LSI
+Fusion-MPS 2 controllers.
+.Pp
+The
+.Nm mprutil
+utility can be used to display or modify various parameters on LSI
+Fusion-MPS 3 controllers.
+.Pp
+The
+.Nm mprutil
+utility behave identically to
+.Nm .
+(same program)
+.Pp
+Each invocation of
+.Nm
+consists of zero or more global options followed by a command.
+Commands may support additional optional or required arguments after the
+command.
+.Pp
+Currently one global option is supported:
+.Bl -tag -width indent
+.It Fl u Ar unit
+.Ar unit
+specifies the unit of the controller to work with.
+If no unit is specified,
+then unit 0 is used.
+.El
+.Pp
+The
+.Nm
+utility supports several different groups of commands.
+The first group of commands provide information about the controller.
+The second group of commands are used to manager controller-wide operations.
+.Pp
+The informational commands include:
+.Bl -tag -width indent
+.It Cm version
+Displays the version of
+.Nm .
+.It Cm show adapter
+Displays information about the controller such as the model number or firmware
+version.
+.It Cm show adapters
+Displays a summary of all adapters.
+.It Cm show all
+Displays all devices, expanders and enclosures.
+.It Cm show devices
+Displays all devices.
+.It Cm show expanders
+Displays all expanders.
+.It Cm show enclosures
+Displays all enclosures.
+.It Cm show iocfacts
+Displays IOC Facts messages.
+.It Cm show cfgpage page Oo Ar num Oc Op Ar addr
+Show IOC Facts Message
+.El
+.Pp
+Controller management commands include:
+.Bl -tag -width indent
+.It Cm flash save Oo Ar firmware Ns | Ns Ar bios Oc Op Ar file
+Save the
+.Ar firmware
+or
+.Ar bios
+from the controller into a local
+.Ar file .
+If no
+.Ar file
+is specified then the file will be named
+.Pa firmware
+or
+.Pa bios .
+.It Cm flash update Oo Ar firmware Ns | Ns Ar bios Oc Ar file
+Replace the
+.Ar firmware
+or
+.Ar bios
+from the controller with the one specified via
+.Ar file .
+.El
+.Sh SEE ALSO
+.Xr mpr 4 ,
+.Xr mps 4
+.Sh HISTORY
+The
+.Nm
+utility first appeared in
+.Fx 11.0 .


Property changes on: trunk/usr.sbin/mpsutil/mpsutil.8
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mpsutil.c
===================================================================
--- trunk/usr.sbin/mpsutil/mpsutil.c	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mpsutil.c	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,208 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Netflix, Inc.
+ * All rights reserved.
+ * Written by: Scott Long <scottl at freebsd.org>
+ *
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$FreeBSD: stable/10/usr.sbin/mpsutil/mpsutil.c 297590 2016-04-05 20:34:20Z sbruno $");
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "mpsutil.h"
+
+SET_DECLARE(MPS_DATASET(top), struct mpsutil_command);
+SET_DECLARE(MPS_DATASET(usage), struct mpsutil_usage);
+
+int mps_unit;
+int is_mps;
+
+static void
+usage(void)
+{
+	struct mpsutil_usage **cmd;
+	const char *args, *desc;
+
+	fprintf(stderr, "usage: %s [-u unit] <command> ...\n\n", getprogname());
+	fprintf(stderr, "Commands include:\n");
+	SET_FOREACH(cmd, MPS_DATASET(usage)) {
+		if (*cmd == NULL)
+			fprintf(stderr, "\n");
+		else
+			(*cmd)->handler(&args, &desc);
+			if (strncmp((*cmd)->set, "top", 3) == 0)
+				fprintf(stderr, "%s %-30s\t%s\n",
+				    (*cmd)->name, args, desc);
+			else
+				fprintf(stderr, "%s %s %-30s\t%s\n",
+				    (*cmd)->set, (*cmd)->name, args, desc);
+	}
+	exit(1);
+}
+
+static int
+version(int ac, char **av)
+{
+
+	printf("%s: version %s", MPSUTIL_VERSION, getprogname());
+#ifdef DEBUG
+	printf(" (DEBUG)");
+#endif
+	printf("\n");
+	return (0);
+}
+
+MPS_COMMAND(top, version, version, "", "version")
+
+int
+main(int ac, char **av)
+{
+	struct mpsutil_command **cmd;
+	int ch;
+
+	is_mps = !strcmp(getprogname(), "mpsutil");
+
+	while ((ch = getopt(ac, av, "u:h?")) != -1) {
+		switch (ch) {
+		case 'u':
+			mps_unit = atoi(optarg);
+			break;
+		case 'h':
+		case '?':
+			usage();
+			return (1);
+		}
+	}
+
+	av += optind;
+	ac -= optind;
+
+	/* getopt() eats av[0], so we can't use mpt_table_handler() directly. */
+	if (ac == 0) {
+		usage();
+		return (1);
+	}
+
+	SET_FOREACH(cmd, MPS_DATASET(top)) {
+		if (strcmp((*cmd)->name, av[0]) == 0) {
+			if ((*cmd)->handler(ac, av))
+				return (1);
+			else
+				return (0);
+		}
+	}
+	warnx("Unknown command %s.", av[0]);
+	return (1);
+}
+
+int
+mps_table_handler(struct mpsutil_command **start, struct mpsutil_command **end,
+    int ac, char **av)
+{
+	struct mpsutil_command **cmd;
+
+	if (ac < 2) {
+		warnx("The %s command requires a sub-command.", av[0]);
+		return (EINVAL);
+	}
+	for (cmd = start; cmd < end; cmd++) {
+		if (strcmp((*cmd)->name, av[1]) == 0)
+			return ((*cmd)->handler(ac - 1, av + 1));
+	}
+
+	warnx("%s is not a valid sub-command of %s.", av[1], av[0]);
+	return (ENOENT);
+}
+
+void
+hexdump(const void *ptr, int length, const char *hdr, int flags)
+{
+	int i, j, k;
+	int cols;
+	const unsigned char *cp;
+	char delim;
+
+	if ((flags & HD_DELIM_MASK) != 0)
+		delim = (flags & HD_DELIM_MASK) >> 8;
+	else
+		delim = ' ';
+
+	if ((flags & HD_COLUMN_MASK) != 0)
+		cols = flags & HD_COLUMN_MASK;
+	else
+		cols = 16;
+
+	cp = ptr;
+	for (i = 0; i < length; i+= cols) {
+		if (hdr != NULL)
+			printf("%s", hdr);
+
+		if ((flags & HD_OMIT_COUNT) == 0)
+			printf("%04x  ", i);
+
+		if ((flags & HD_OMIT_HEX) == 0) {
+			for (j = 0; j < cols; j++) {
+				if (flags & HD_REVERSED)
+					k = i + (cols - 1 - j);
+				else
+					k = i + j;
+				if (k < length)
+					printf("%c%02x", delim, cp[k]);
+				else
+					printf("   ");
+			}
+		}
+
+		if ((flags & HD_OMIT_CHARS) == 0) {
+			printf("  |");
+			for (j = 0; j < cols; j++) {
+				if (flags & HD_REVERSED)
+					k = i + (cols - 1 - j);
+				else
+					k = i + j;
+				if (k >= length)
+					printf(" ");
+				else if (cp[k] >= ' ' && cp[k] <= '~')
+					printf("%c", cp[k]);
+				else
+					printf(".");
+			}
+			printf("|");
+		}
+		printf("\n");
+	}
+}


Property changes on: trunk/usr.sbin/mpsutil/mpsutil.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/usr.sbin/mpsutil/mpsutil.h
===================================================================
--- trunk/usr.sbin/mpsutil/mpsutil.h	                        (rev 0)
+++ trunk/usr.sbin/mpsutil/mpsutil.h	2018-06-03 23:26:13 UTC (rev 10380)
@@ -0,0 +1,148 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb at FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the author nor the names of any co-contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/usr.sbin/mpsutil/mpsutil.h 297590 2016-04-05 20:34:20Z sbruno $
+ */
+
+#ifndef __MPSUTIL_H__
+#define	__MPSUTIL_H__
+
+#include <sys/cdefs.h>
+#include <sys/linker_set.h>
+#include <stdbool.h>
+
+#include <dev/mps/mpi/mpi2_type.h>
+#include <dev/mps/mpi/mpi2.h>
+#include <dev/mps/mpi/mpi2_cnfg.h>
+#include <dev/mps/mpi/mpi2_raid.h>
+#include <dev/mps/mpi/mpi2_ioc.h>
+
+#define MPSUTIL_VERSION	"1.0.0"
+
+#define	IOC_STATUS_SUCCESS(status)					\
+	(((status) & MPI2_IOCSTATUS_MASK) == MPI2_IOCSTATUS_SUCCESS)
+
+struct mpsutil_command {
+	const char *name;
+	int (*handler)(int ac, char **av);
+};
+struct mpsutil_usage {
+	const char *set;
+	const char *name;
+	void (*handler)(const char **, const char**);
+};
+
+#define	MPS_DATASET(name)	mpsutil_ ## name ## _table
+
+#define	MPS_COMMAND(set, name, function, args, desc)			\
+	static struct mpsutil_command function ## _mpsutil_command =	\
+	{ #name, function };						\
+	DATA_SET(MPS_DATASET(set), function ## _mpsutil_command);	\
+	static void							\
+	function ## _usage(const char **a3, const char **a4)		\
+	{								\
+		*a3 = args;						\
+		*a4 = desc;						\
+		return;							\
+	};								\
+	static struct mpsutil_usage function ## _mpsutil_usage =	\
+	{ #set, #name, function ## _usage };				\
+	DATA_SET(MPS_DATASET(usage), function ## _mpsutil_usage);
+
+#define	_MPS_COMMAND(set, name, function)				\
+	static struct mpsutil_command function ## _mpsutil_command =	\
+	{ #name, function };						\
+	DATA_SET(MPS_DATASET(set), function ## _mpsutil_command);
+
+#define	MPS_TABLE(set, name)						\
+	SET_DECLARE(MPS_DATASET(name), struct mpsutil_command);		\
+									\
+	static int							\
+	mpsutil_ ## name ## _table_handler(int ac, char **av)		\
+	{								\
+		return (mps_table_handler(SET_BEGIN(MPS_DATASET(name)), \
+		    SET_LIMIT(MPS_DATASET(name)), ac, av));		\
+	}								\
+	_MPS_COMMAND(set, name, mpsutil_ ## name ## _table_handler)
+
+extern int mps_unit;
+extern int is_mps;
+#define MPS_MAX_UNIT 10
+
+void	hexdump(const void *ptr, int length, const char *hdr, int flags);
+#define	HD_COLUMN_MASK	0xff
+#define	HD_DELIM_MASK	0xff00
+#define	HD_OMIT_COUNT	(1 << 16)
+#define	HD_OMIT_HEX	(1 << 17)
+#define	HD_OMIT_CHARS	(1 << 18)
+#define HD_REVERSED	(1 << 19)
+
+int	mps_open(int unit);
+int	mps_table_handler(struct mpsutil_command **start,
+    struct mpsutil_command **end, int ac, char **av);
+int	mps_user_command(int fd, void *req, uint32_t req_len, void *reply,
+	uint32_t reply_len, void *buffer, int len, uint32_t flags);
+int	mps_pass_command(int fd, void *req, uint32_t req_len, void *reply,
+	uint32_t reply_len, void *data_in, uint32_t datain_len, void *data_out,
+	uint32_t dataout_len, uint32_t timeout);
+int	mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber,
+    U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus);
+int	mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber,
+    U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header,
+    U16 *ExtPageLen, U16 *IOCStatus);
+void	*mps_read_config_page(int fd, U8 PageType, U8 PageNumber,
+    U32 PageAddress, U16 *IOCStatus);
+void	*mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
+    U8 PageNumber, U32 PageAddress, U16 *IOCStatus);
+int	mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus,
+    uint16_t *target);
+const char *mps_ioc_status(U16 IOCStatus);
+int	mps_firmware_send(int fd, unsigned char *buf, uint32_t len, bool bios);
+int	mps_firmware_get(int fd, unsigned char **buf, bool bios);
+
+static __inline void *
+mps_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus)
+{
+
+	return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_MANUFACTURING,
+	    PageNumber, 0, IOCStatus));
+}
+
+static __inline void *
+mps_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus)
+{
+
+	return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_IOC, PageNumber,
+	    0, IOCStatus));
+}
+
+MPI2_IOC_FACTS_REPLY * mps_get_iocfacts(int fd);
+
+#endif /* !__MPSUTIL_H__ */


Property changes on: trunk/usr.sbin/mpsutil/mpsutil.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property


More information about the Midnightbsd-cvs mailing list