155714Skris/*- 2296465Sdelphij * Copyright (c) 2008 Yahoo!, Inc. 359191Skris * All rights reserved. 4109998Smarkm * Written by: John Baldwin <jhb@FreeBSD.org> 5109998Smarkm * 659191Skris * Redistribution and use in source and binary forms, with or without 755714Skris * modification, are permitted provided that the following conditions 855714Skris * are met: 955714Skris * 1. Redistributions of source code must retain the above copyright 1055714Skris * notice, this list of conditions and the following disclaimer. 1155714Skris * 2. Redistributions in binary form must reproduce the above copyright 1255714Skris * notice, this list of conditions and the following disclaimer in the 13296465Sdelphij * documentation and/or other materials provided with the distribution. 1455714Skris * 3. Neither the name of the author nor the names of any co-contributors 1555714Skris * may be used to endorse or promote products derived from this software 1655714Skris * without specific prior written permission. 1755714Skris * 1855714Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1955714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20296465Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2155714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2255714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2355714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2455714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2555714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2655714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27296465Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2855714Skris * SUCH DAMAGE. 2955714Skris */ 3055714Skris 3155714Skris#ifndef __MPSUTIL_H__ 3255714Skris#define __MPSUTIL_H__ 3355714Skris 3455714Skris#include <sys/cdefs.h> 3555714Skris#include <sys/linker_set.h> 3655714Skris#include <stdbool.h> 3755714Skris 3855714Skris#include <dev/mps/mpi/mpi2_type.h> 3955714Skris#include <dev/mps/mpi/mpi2.h> 4055714Skris#include <dev/mps/mpi/mpi2_cnfg.h> 4155714Skris#include <dev/mps/mpi/mpi2_raid.h> 42296465Sdelphij#include <dev/mps/mpi/mpi2_ioc.h> 4355714Skris#include <dev/mps/mpi/mpi2_init.h> 4455714Skris#include <dev/mps/mpi/mpi2_tool.h> 45296465Sdelphij 4655714Skris#define MPSUTIL_VERSION "1.0.0" 4755714Skris 4855714Skris#define IOC_STATUS_SUCCESS(status) \ 4955714Skris (((status) & MPI2_IOCSTATUS_MASK) == MPI2_IOCSTATUS_SUCCESS) 5055714Skris 5155714Skrisstruct mpsutil_command { 5255714Skris const char *name; 5355714Skris int (*handler)(int ac, char **av); 5455714Skris}; 5555714Skrisstruct mpsutil_usage { 5655714Skris const char *set; 57296465Sdelphij const char *name; 5855714Skris void (*handler)(const char **, const char**); 5955714Skris}; 6055714Skris 6155714Skris#define MPS_DATASET(name) mpsutil_ ## name ## _table 6255714Skris 6355714Skris#define MPS_COMMAND(set, name, function, args, desc) \ 6455714Skris static struct mpsutil_command function ## _mpsutil_command = \ 6555714Skris { #name, function }; \ 6655714Skris DATA_SET(MPS_DATASET(set), function ## _mpsutil_command); \ 67109998Smarkm static void \ 68296465Sdelphij function ## _usage(const char **a3, const char **a4) \ 6955714Skris { \ 70296465Sdelphij *a3 = args; \ 71296465Sdelphij *a4 = desc; \ 72296465Sdelphij return; \ 7355714Skris }; \ 74296465Sdelphij static struct mpsutil_usage function ## _mpsutil_usage = \ 75296465Sdelphij { #set, #name, function ## _usage }; \ 76296465Sdelphij DATA_SET(MPS_DATASET(usage), function ## _mpsutil_usage); 77296465Sdelphij 78296465Sdelphij#define _MPS_COMMAND(set, name, function) \ 79296465Sdelphij static struct mpsutil_command function ## _mpsutil_command = \ 8055714Skris { #name, function }; \ 81296465Sdelphij DATA_SET(MPS_DATASET(set), function ## _mpsutil_command); 8255714Skris 83296465Sdelphij#define MPS_TABLE(set, name) \ 84296465Sdelphij SET_DECLARE(MPS_DATASET(name), struct mpsutil_command); \ 85296465Sdelphij \ 86296465Sdelphij static int \ 87296465Sdelphij mpsutil_ ## name ## _table_handler(int ac, char **av) \ 88296465Sdelphij { \ 89296465Sdelphij return (mps_table_handler(SET_BEGIN(MPS_DATASET(name)), \ 90296465Sdelphij SET_LIMIT(MPS_DATASET(name)), ac, av)); \ 91296465Sdelphij } \ 92296465Sdelphij _MPS_COMMAND(set, name, mpsutil_ ## name ## _table_handler) 93296465Sdelphij 94296465Sdelphijextern int mps_unit; 95296465Sdelphijextern int is_mps; 96296465Sdelphij#define MPS_MAX_UNIT 10 97296465Sdelphij 98296465Sdelphijvoid hexdump(const void *ptr, int length, const char *hdr, int flags); 99296465Sdelphij#define HD_COLUMN_MASK 0xff 100296465Sdelphij#define HD_DELIM_MASK 0xff00 101296465Sdelphij#define HD_OMIT_COUNT (1 << 16) 102296465Sdelphij#define HD_OMIT_HEX (1 << 17) 103296465Sdelphij#define HD_OMIT_CHARS (1 << 18) 104296465Sdelphij#define HD_REVERSED (1 << 19) 105296465Sdelphijint mps_parse_flags(uintmax_t, const char *, char *, int); 106296465Sdelphij 107296465Sdelphijint mps_open(int unit); 108296465Sdelphijint mps_table_handler(struct mpsutil_command **start, 109296465Sdelphij struct mpsutil_command **end, int ac, char **av); 110296465Sdelphijint mps_user_command(int fd, void *req, uint32_t req_len, void *reply, 11155714Skris uint32_t reply_len, void *buffer, int len, uint32_t flags); 112296465Sdelphijint mps_pass_command(int fd, void *req, uint32_t req_len, void *reply, 113296465Sdelphij uint32_t reply_len, void *data_in, uint32_t datain_len, void *data_out, 114296465Sdelphij uint32_t dataout_len, uint32_t timeout); 11555714Skrisint mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, 116296465Sdelphij U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus); 117296465Sdelphijint mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber, 118296465Sdelphij U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, 119296465Sdelphij U16 *ExtPageLen, U16 *IOCStatus); 120296465Sdelphijvoid *mps_read_config_page(int fd, U8 PageType, U8 PageNumber, 121296465Sdelphij U32 PageAddress, U16 *IOCStatus); 122296465Sdelphijvoid *mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, 123296465Sdelphij U8 PageNumber, U32 PageAddress, U16 *IOCStatus); 124296465Sdelphijint mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus, 125296465Sdelphij uint16_t *target); 126296465Sdelphijconst char *mps_ioc_status(U16 IOCStatus); 127296465Sdelphijint mps_firmware_send(int fd, unsigned char *buf, uint32_t len, bool bios); 128296465Sdelphijint mps_firmware_get(int fd, unsigned char **buf, bool bios); 129296465Sdelphijint mps_set_slot_status(int fd, U16 handle, U16 slot, U32 status); 130296465Sdelphij 131296465Sdelphijstatic __inline void * 132296465Sdelphijmps_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus) 133296465Sdelphij{ 134296465Sdelphij 135296465Sdelphij return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 136296465Sdelphij PageNumber, 0, IOCStatus)); 137296465Sdelphij} 138296465Sdelphij 139296465Sdelphijstatic __inline void * 140296465Sdelphijmps_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus) 14155714Skris{ 142296465Sdelphij 143296465Sdelphij return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_IOC, PageNumber, 14455714Skris 0, IOCStatus)); 145296465Sdelphij} 146296465Sdelphij 147296465Sdelphijstatic __inline uint64_t 148296465Sdelphijmps_to_u64(U64 *data) 149296465Sdelphij{ 15055714Skris 151296465Sdelphij return (((uint64_t)(data->High) << 32 ) | data->Low); 152296465Sdelphij} 153296465Sdelphij 154296465SdelphijMPI2_IOC_FACTS_REPLY * mps_get_iocfacts(int fd); 155 156#endif /* !__MPSUTIL_H__ */ 157