svn commit: r286180 - projects/mpsutil/usr.sbin/mpsutil
Scott Long
scottl at FreeBSD.org
Sun Aug 2 03:52:53 UTC 2015
Author: scottl
Date: Sun Aug 2 03:52:51 2015
New Revision: 286180
URL: https://svnweb.freebsd.org/changeset/base/286180
Log:
Iniital hack of mpsutil
Added:
projects/mpsutil/usr.sbin/mpsutil/
projects/mpsutil/usr.sbin/mpsutil/Makefile (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mpr_ioctl.h (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mps_cmd.c (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mps_config.c (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mps_ioctl.h (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mps_mpr.diff
projects/mpsutil/usr.sbin/mpsutil/mps_show.c (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mpsutil.8 (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mpsutil.c (contents, props changed)
projects/mpsutil/usr.sbin/mpsutil/mpsutil.h (contents, props changed)
Added: projects/mpsutil/usr.sbin/mpsutil/Makefile
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/mpsutil/usr.sbin/mpsutil/Makefile Sun Aug 2 03:52:51 2015 (r286180)
@@ -0,0 +1,20 @@
+# $FreeBSD$
+
+PROG= mpsutil
+SRCS= mpsutil.c mps_cmd.c mps_show.c
+# mpt_flash.c
+MAN= mpsutil.8
+
+WARNS?= 3
+
+LIBADD= cam util
+
+CFLAGS+= -I../../sys -I. -DUSE_MPT_IOCTLS -g
+
+
+# Here be dragons
+.ifdef DEBUG
+CFLAGS+= -DDEBUG
+.endif
+
+.include <bsd.prog.mk>
Added: projects/mpsutil/usr.sbin/mpsutil/mpr_ioctl.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/mpsutil/usr.sbin/mpsutil/mpr_ioctl.h Sun Aug 2 03:52:51 2015 (r286180)
@@ -0,0 +1,386 @@
+/*-
+ * 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$
+ */
+/*-
+ * 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)
+
+#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 /* !_MPR_IOCTL_H_ */
Added: projects/mpsutil/usr.sbin/mpsutil/mps_cmd.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ projects/mpsutil/usr.sbin/mpsutil/mps_cmd.c Sun Aug 2 03:52:51 2015 (r286180)
@@ -0,0 +1,713 @@
+/*-
+ * 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$");
+
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#if 0
+#include <sys/mps_ioctl.h>
+#else
+#include "mps_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 */
+};
+
+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 mps_btdh_mapping map;
+
+ bzero(&map, sizeof(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);
+}
+
+#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
+
+#if 0
+int
+mpt_write_config_page(int fd, void *buf, U16 *IOCStatus)
+{
+ CONFIG_PAGE_HEADER *hdr;
+ struct mpt_cfg_page_req req;
+
+ if (IOCStatus != NULL)
+ *IOCStatus = MPI_IOCSTATUS_SUCCESS;
+ bzero(&req, sizeof(req));
+ req.buf = buf;
+ hdr = buf;
+ req.len = hdr->PageLength * 4;
+ if (ioctl(fd, MPTIO_WRITE_CFG_PAGE, &req) < 0)
+ return (errno);
+ if (!IOC_STATUS_SUCCESS(req.ioc_status)) {
+ if (IOCStatus != NULL) {
+ *IOCStatus = req.ioc_status;
+ return (0);
+ }
+ warnx("Writing config page failed: %s",
+ mpt_ioc_status(req.ioc_status));
+ return (EIO);
+ }
+ return (0);
+}
+
+int
+mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum,
+ U32 ActionDataWord, void *buf, int len, RAID_VOL0_STATUS *VolumeStatus,
+ U32 *ActionData, int datalen, U16 *IOCStatus, U16 *ActionStatus, int write)
+{
+ struct mpt_raid_action raid_act;
+
+ if (IOCStatus != NULL)
+ *IOCStatus = MPI_IOCSTATUS_SUCCESS;
+ if (datalen < 0 || (unsigned)datalen > sizeof(raid_act.action_data))
+ return (EINVAL);
+ bzero(&raid_act, sizeof(raid_act));
+ raid_act.action = Action;
+ raid_act.volume_bus = VolumeBus;
+ raid_act.volume_id = VolumeID;
+ raid_act.phys_disk_num = PhysDiskNum;
+ raid_act.action_data_word = ActionDataWord;
+ if (buf != NULL && len != 0) {
+ raid_act.buf = buf;
+ raid_act.len = len;
+ raid_act.write = write;
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-projects
mailing list