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 <j...@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 <b...@freebsd.org>
+ *
+ * Copyright (c) 2015 Netflix, Inc.
+ * All rights reserved.
+ * Written by: Scott Long <sco...@freebsd.org>
+ *
+ * Copyright (c) 2008 Yahoo!, Inc.
+ * All rights reserved.
+ * Written by: John Baldwin <j...@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 ***
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to