1297590Ssbruno/*- 2297590Ssbruno * Copyright (c) 2008 Yahoo!, Inc. 3297590Ssbruno * All rights reserved. 4297590Ssbruno * Written by: John Baldwin <jhb@FreeBSD.org> 5297590Ssbruno * 6297590Ssbruno * Redistribution and use in source and binary forms, with or without 7297590Ssbruno * modification, are permitted provided that the following conditions 8297590Ssbruno * are met: 9297590Ssbruno * 1. Redistributions of source code must retain the above copyright 10297590Ssbruno * notice, this list of conditions and the following disclaimer. 11297590Ssbruno * 2. Redistributions in binary form must reproduce the above copyright 12297590Ssbruno * notice, this list of conditions and the following disclaimer in the 13297590Ssbruno * documentation and/or other materials provided with the distribution. 14297590Ssbruno * 3. Neither the name of the author nor the names of any co-contributors 15297590Ssbruno * may be used to endorse or promote products derived from this software 16297590Ssbruno * without specific prior written permission. 17297590Ssbruno * 18297590Ssbruno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19297590Ssbruno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20297590Ssbruno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21297590Ssbruno * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22297590Ssbruno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23297590Ssbruno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24297590Ssbruno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25297590Ssbruno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26297590Ssbruno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27297590Ssbruno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28297590Ssbruno * SUCH DAMAGE. 29297590Ssbruno * 30297590Ssbruno * $FreeBSD$ 31297590Ssbruno */ 32297590Ssbruno 33297590Ssbruno#ifndef __MPSUTIL_H__ 34297590Ssbruno#define __MPSUTIL_H__ 35297590Ssbruno 36297590Ssbruno#include <sys/cdefs.h> 37297590Ssbruno#include <sys/linker_set.h> 38297590Ssbruno#include <stdbool.h> 39297590Ssbruno 40297590Ssbruno#include <dev/mps/mpi/mpi2_type.h> 41297590Ssbruno#include <dev/mps/mpi/mpi2.h> 42297590Ssbruno#include <dev/mps/mpi/mpi2_cnfg.h> 43297590Ssbruno#include <dev/mps/mpi/mpi2_raid.h> 44297590Ssbruno#include <dev/mps/mpi/mpi2_ioc.h> 45297590Ssbruno 46297590Ssbruno#define MPSUTIL_VERSION "1.0.0" 47297590Ssbruno 48297590Ssbruno#define IOC_STATUS_SUCCESS(status) \ 49297590Ssbruno (((status) & MPI2_IOCSTATUS_MASK) == MPI2_IOCSTATUS_SUCCESS) 50297590Ssbruno 51297590Ssbrunostruct mpsutil_command { 52297590Ssbruno const char *name; 53297590Ssbruno int (*handler)(int ac, char **av); 54297590Ssbruno}; 55297590Ssbrunostruct mpsutil_usage { 56297590Ssbruno const char *set; 57297590Ssbruno const char *name; 58297590Ssbruno void (*handler)(const char **, const char**); 59297590Ssbruno}; 60297590Ssbruno 61297590Ssbruno#define MPS_DATASET(name) mpsutil_ ## name ## _table 62297590Ssbruno 63297590Ssbruno#define MPS_COMMAND(set, name, function, args, desc) \ 64297590Ssbruno static struct mpsutil_command function ## _mpsutil_command = \ 65297590Ssbruno { #name, function }; \ 66297590Ssbruno DATA_SET(MPS_DATASET(set), function ## _mpsutil_command); \ 67297590Ssbruno static void \ 68297590Ssbruno function ## _usage(const char **a3, const char **a4) \ 69297590Ssbruno { \ 70297590Ssbruno *a3 = args; \ 71297590Ssbruno *a4 = desc; \ 72297590Ssbruno return; \ 73297590Ssbruno }; \ 74297590Ssbruno static struct mpsutil_usage function ## _mpsutil_usage = \ 75297590Ssbruno { #set, #name, function ## _usage }; \ 76297590Ssbruno DATA_SET(MPS_DATASET(usage), function ## _mpsutil_usage); 77297590Ssbruno 78297590Ssbruno#define _MPS_COMMAND(set, name, function) \ 79297590Ssbruno static struct mpsutil_command function ## _mpsutil_command = \ 80297590Ssbruno { #name, function }; \ 81297590Ssbruno DATA_SET(MPS_DATASET(set), function ## _mpsutil_command); 82297590Ssbruno 83297590Ssbruno#define MPS_TABLE(set, name) \ 84297590Ssbruno SET_DECLARE(MPS_DATASET(name), struct mpsutil_command); \ 85297590Ssbruno \ 86297590Ssbruno static int \ 87297590Ssbruno mpsutil_ ## name ## _table_handler(int ac, char **av) \ 88297590Ssbruno { \ 89297590Ssbruno return (mps_table_handler(SET_BEGIN(MPS_DATASET(name)), \ 90297590Ssbruno SET_LIMIT(MPS_DATASET(name)), ac, av)); \ 91297590Ssbruno } \ 92297590Ssbruno _MPS_COMMAND(set, name, mpsutil_ ## name ## _table_handler) 93297590Ssbruno 94297590Ssbrunoextern int mps_unit; 95297590Ssbrunoextern int is_mps; 96297590Ssbruno#define MPS_MAX_UNIT 10 97297590Ssbruno 98297590Ssbrunovoid hexdump(const void *ptr, int length, const char *hdr, int flags); 99297590Ssbruno#define HD_COLUMN_MASK 0xff 100297590Ssbruno#define HD_DELIM_MASK 0xff00 101297590Ssbruno#define HD_OMIT_COUNT (1 << 16) 102297590Ssbruno#define HD_OMIT_HEX (1 << 17) 103297590Ssbruno#define HD_OMIT_CHARS (1 << 18) 104297590Ssbruno#define HD_REVERSED (1 << 19) 105297590Ssbruno 106297590Ssbrunoint mps_open(int unit); 107297590Ssbrunoint mps_table_handler(struct mpsutil_command **start, 108297590Ssbruno struct mpsutil_command **end, int ac, char **av); 109297590Ssbrunoint mps_user_command(int fd, void *req, uint32_t req_len, void *reply, 110297590Ssbruno uint32_t reply_len, void *buffer, int len, uint32_t flags); 111297590Ssbrunoint mps_pass_command(int fd, void *req, uint32_t req_len, void *reply, 112297590Ssbruno uint32_t reply_len, void *data_in, uint32_t datain_len, void *data_out, 113297590Ssbruno uint32_t dataout_len, uint32_t timeout); 114297590Ssbrunoint mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber, 115297590Ssbruno U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus); 116297590Ssbrunoint mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber, 117297590Ssbruno U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, 118297590Ssbruno U16 *ExtPageLen, U16 *IOCStatus); 119297590Ssbrunovoid *mps_read_config_page(int fd, U8 PageType, U8 PageNumber, 120297590Ssbruno U32 PageAddress, U16 *IOCStatus); 121297590Ssbrunovoid *mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, 122297590Ssbruno U8 PageNumber, U32 PageAddress, U16 *IOCStatus); 123297590Ssbrunoint mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus, 124297590Ssbruno uint16_t *target); 125297590Ssbrunoconst char *mps_ioc_status(U16 IOCStatus); 126297590Ssbrunoint mps_firmware_send(int fd, unsigned char *buf, uint32_t len, bool bios); 127297590Ssbrunoint mps_firmware_get(int fd, unsigned char **buf, bool bios); 128297590Ssbruno 129297590Ssbrunostatic __inline void * 130297590Ssbrunomps_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus) 131297590Ssbruno{ 132297590Ssbruno 133297590Ssbruno return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_MANUFACTURING, 134297590Ssbruno PageNumber, 0, IOCStatus)); 135297590Ssbruno} 136297590Ssbruno 137297590Ssbrunostatic __inline void * 138297590Ssbrunomps_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus) 139297590Ssbruno{ 140297590Ssbruno 141297590Ssbruno return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_IOC, PageNumber, 142297590Ssbruno 0, IOCStatus)); 143297590Ssbruno} 144297590Ssbruno 145297590SsbrunoMPI2_IOC_FACTS_REPLY * mps_get_iocfacts(int fd); 146297590Ssbruno 147297590Ssbruno#endif /* !__MPSUTIL_H__ */ 148