1/*-
2 * Copyright (c) 2008 Yahoo!, Inc.
3 * All rights reserved.
4 * Written by: John Baldwin <jhb@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the author nor the names of any co-contributors
15 *    may be used to endorse or promote products derived from this software
16 *    without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 *
30 * $FreeBSD$
31 */
32
33#ifndef __MPSUTIL_H__
34#define	__MPSUTIL_H__
35
36#include <sys/cdefs.h>
37#include <sys/linker_set.h>
38#include <stdbool.h>
39
40#include <dev/mps/mpi/mpi2_type.h>
41#include <dev/mps/mpi/mpi2.h>
42#include <dev/mps/mpi/mpi2_cnfg.h>
43#include <dev/mps/mpi/mpi2_raid.h>
44#include <dev/mps/mpi/mpi2_ioc.h>
45#include <dev/mps/mpi/mpi2_init.h>
46#include <dev/mps/mpi/mpi2_tool.h>
47
48#define MPSUTIL_VERSION	"1.0.0"
49
50#define	IOC_STATUS_SUCCESS(status)					\
51	(((status) & MPI2_IOCSTATUS_MASK) == MPI2_IOCSTATUS_SUCCESS)
52
53struct mpsutil_command {
54	const char *name;
55	int (*handler)(int ac, char **av);
56};
57struct mpsutil_usage {
58	const char *set;
59	const char *name;
60	void (*handler)(const char **, const char**);
61};
62
63#define	MPS_DATASET(name)	mpsutil_ ## name ## _table
64
65#define	MPS_COMMAND(set, name, function, args, desc)			\
66	static struct mpsutil_command function ## _mpsutil_command =	\
67	{ #name, function };						\
68	DATA_SET(MPS_DATASET(set), function ## _mpsutil_command);	\
69	static void							\
70	function ## _usage(const char **a3, const char **a4)		\
71	{								\
72		*a3 = args;						\
73		*a4 = desc;						\
74		return;							\
75	};								\
76	static struct mpsutil_usage function ## _mpsutil_usage =	\
77	{ #set, #name, function ## _usage };				\
78	DATA_SET(MPS_DATASET(usage), function ## _mpsutil_usage);
79
80#define	_MPS_COMMAND(set, name, function)				\
81	static struct mpsutil_command function ## _mpsutil_command =	\
82	{ #name, function };						\
83	DATA_SET(MPS_DATASET(set), function ## _mpsutil_command);
84
85#define	MPS_TABLE(set, name)						\
86	SET_DECLARE(MPS_DATASET(name), struct mpsutil_command);		\
87									\
88	static int							\
89	mpsutil_ ## name ## _table_handler(int ac, char **av)		\
90	{								\
91		return (mps_table_handler(SET_BEGIN(MPS_DATASET(name)), \
92		    SET_LIMIT(MPS_DATASET(name)), ac, av));		\
93	}								\
94	_MPS_COMMAND(set, name, mpsutil_ ## name ## _table_handler)
95
96extern int mps_unit;
97extern int is_mps;
98#define MPS_MAX_UNIT 10
99
100void	hexdump(const void *ptr, int length, const char *hdr, int flags);
101#define	HD_COLUMN_MASK	0xff
102#define	HD_DELIM_MASK	0xff00
103#define	HD_OMIT_COUNT	(1 << 16)
104#define	HD_OMIT_HEX	(1 << 17)
105#define	HD_OMIT_CHARS	(1 << 18)
106#define HD_REVERSED	(1 << 19)
107int	mps_parse_flags(uintmax_t, const char *, char *, int);
108
109int	mps_open(int unit);
110int	mps_table_handler(struct mpsutil_command **start,
111    struct mpsutil_command **end, int ac, char **av);
112int	mps_user_command(int fd, void *req, uint32_t req_len, void *reply,
113	uint32_t reply_len, void *buffer, int len, uint32_t flags);
114int	mps_pass_command(int fd, void *req, uint32_t req_len, void *reply,
115	uint32_t reply_len, void *data_in, uint32_t datain_len, void *data_out,
116	uint32_t dataout_len, uint32_t timeout);
117int	mps_read_config_page_header(int fd, U8 PageType, U8 PageNumber,
118    U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header, U16 *IOCStatus);
119int	mps_read_ext_config_page_header(int fd, U8 ExtPageType, U8 PageNumber,
120    U32 PageAddress, MPI2_CONFIG_PAGE_HEADER *header,
121    U16 *ExtPageLen, U16 *IOCStatus);
122void	*mps_read_config_page(int fd, U8 PageType, U8 PageNumber,
123    U32 PageAddress, U16 *IOCStatus);
124void	*mps_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
125    U8 PageNumber, U32 PageAddress, U16 *IOCStatus);
126int	mps_map_btdh(int fd, uint16_t *devhandle, uint16_t *bus,
127    uint16_t *target);
128const char *mps_ioc_status(U16 IOCStatus);
129int	mps_firmware_send(int fd, unsigned char *buf, uint32_t len, bool bios);
130int	mps_firmware_get(int fd, unsigned char **buf, bool bios);
131int	mps_set_slot_status(int fd, U16 handle, U16 slot, U32 status);
132
133static __inline void *
134mps_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus)
135{
136
137	return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_MANUFACTURING,
138	    PageNumber, 0, IOCStatus));
139}
140
141static __inline void *
142mps_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus)
143{
144
145	return (mps_read_config_page(fd, MPI2_CONFIG_PAGETYPE_IOC, PageNumber,
146	    0, IOCStatus));
147}
148
149static __inline uint64_t
150mps_to_u64(U64 *data)
151{
152
153	return (((uint64_t)(data->High) << 32 ) | data->Low);
154}
155
156MPI2_IOC_FACTS_REPLY * mps_get_iocfacts(int fd);
157
158#endif /* !__MPSUTIL_H__ */
159