Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Apr 2016 20:34:20 +0000 (UTC)
From:      Sean Bruno <sbruno@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r297590 - in stable/10/usr.sbin: . mpsutil
Message-ID:  <201604052034.u35KYKQu040239@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sbruno
Date: Tue Apr  5 20:34:20 2016
New Revision: 297590
URL: https://svnweb.freebsd.org/changeset/base/297590

Log:
  MFC 290102
  
  - Include usr.sbin/mpsutil for management of mps(4) and mpr(4) utilities.
  
  - Thanks to scottl and bapt for making this happen.
  
  Submitted by:	bapt scottl
  Reviewed by:	kbowling
  Relnotes:	yes
  Differential Revision:	https://reviews.freebsd.org/D5529

Added:
  stable/10/usr.sbin/mpsutil/
  stable/10/usr.sbin/mpsutil/Makefile   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mpr_ioctl.h   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mps_cmd.c   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mps_flash.c   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mps_ioctl.h   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mps_show.c   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mpsutil.8   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mpsutil.c   (contents, props changed)
  stable/10/usr.sbin/mpsutil/mpsutil.h   (contents, props changed)
Modified:
  stable/10/usr.sbin/Makefile
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/Makefile
==============================================================================
--- stable/10/usr.sbin/Makefile	Tue Apr  5 19:30:19 2016	(r297589)
+++ stable/10/usr.sbin/Makefile	Tue Apr  5 20:34:20 2016	(r297590)
@@ -46,6 +46,7 @@ SUBDIR=	adduser \
 	mlxcontrol \
 	mountd \
 	mount_smbfs \
+	mpsutil \
 	mptutil \
 	mtest \
 	${_mtree} \

Added: stable/10/usr.sbin/mpsutil/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/usr.sbin/mpsutil/Makefile	Tue Apr  5 20:34:20 2016	(r297590)
@@ -0,0 +1,21 @@
+# $FreeBSD$
+
+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>

Added: stable/10/usr.sbin/mpsutil/mpr_ioctl.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/usr.sbin/mpsutil/mpr_ioctl.h	Tue Apr  5 20:34:20 2016	(r297590)
@@ -0,0 +1,388 @@
+/*-
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb@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$
+ */
+/*-
+ * 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$
+ */
+
+#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_ */

Added: stable/10/usr.sbin/mpsutil/mps_cmd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/10/usr.sbin/mpsutil/mps_cmd.c	Tue Apr  5 20:34:20 2016	(r297590)
@@ -0,0 +1,731 @@
+/*-
+ * Copyright (c) 2015 Baptiste Daroussin <bapt@FreeBSD.org>
+ *
+ * Copyright (c) 2015 Netflix, Inc.
+ * All rights reserved.
+ * Written by: Scott Long <scottl@freebsd.org>
+ *
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <jhb@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$");
+
+#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(1, sizeof(unsigned char) * size);
+	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)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604052034.u35KYKQu040239>