122b2e3c5SAlexander Polakov /*-
222b2e3c5SAlexander Polakov * Copyright (c) 2008 Yahoo!, Inc.
322b2e3c5SAlexander Polakov * All rights reserved.
422b2e3c5SAlexander Polakov * Written by: John Baldwin <jhb@FreeBSD.org>
522b2e3c5SAlexander Polakov *
622b2e3c5SAlexander Polakov * Redistribution and use in source and binary forms, with or without
722b2e3c5SAlexander Polakov * modification, are permitted provided that the following conditions
822b2e3c5SAlexander Polakov * are met:
922b2e3c5SAlexander Polakov * 1. Redistributions of source code must retain the above copyright
1022b2e3c5SAlexander Polakov * notice, this list of conditions and the following disclaimer.
1122b2e3c5SAlexander Polakov * 2. Redistributions in binary form must reproduce the above copyright
1222b2e3c5SAlexander Polakov * notice, this list of conditions and the following disclaimer in the
1322b2e3c5SAlexander Polakov * documentation and/or other materials provided with the distribution.
1422b2e3c5SAlexander Polakov * 3. Neither the name of the author nor the names of any co-contributors
1522b2e3c5SAlexander Polakov * may be used to endorse or promote products derived from this software
1622b2e3c5SAlexander Polakov * without specific prior written permission.
1722b2e3c5SAlexander Polakov *
1822b2e3c5SAlexander Polakov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1922b2e3c5SAlexander Polakov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2022b2e3c5SAlexander Polakov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2122b2e3c5SAlexander Polakov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2222b2e3c5SAlexander Polakov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2322b2e3c5SAlexander Polakov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2422b2e3c5SAlexander Polakov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2522b2e3c5SAlexander Polakov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2622b2e3c5SAlexander Polakov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2722b2e3c5SAlexander Polakov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2822b2e3c5SAlexander Polakov * SUCH DAMAGE.
2922b2e3c5SAlexander Polakov *
3022b2e3c5SAlexander Polakov * $FreeBSD: src/usr.sbin/mptutil/mptutil.h,v 1.1 2009/08/14 13:13:12 scottl Exp $
3122b2e3c5SAlexander Polakov */
3222b2e3c5SAlexander Polakov
3322b2e3c5SAlexander Polakov #ifndef __MPTUTIL_H__
3422b2e3c5SAlexander Polakov #define __MPTUTIL_H__
3522b2e3c5SAlexander Polakov
3622b2e3c5SAlexander Polakov #include <sys/linker_set.h>
3722b2e3c5SAlexander Polakov
38*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi_type.h>
39*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi.h>
40*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi_cnfg.h>
41*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi_raid.h>
42*92734026SAlexander Polakov
4322b2e3c5SAlexander Polakov #define IOC_STATUS_SUCCESS(status) \
4422b2e3c5SAlexander Polakov (((status) & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS)
4522b2e3c5SAlexander Polakov
4622b2e3c5SAlexander Polakov struct mpt_query_disk {
4722b2e3c5SAlexander Polakov char devname[SPECNAMELEN + 1];
4822b2e3c5SAlexander Polakov };
4922b2e3c5SAlexander Polakov
5022b2e3c5SAlexander Polakov struct mpt_standalone_disk {
5122b2e3c5SAlexander Polakov uint64_t maxlba;
5222b2e3c5SAlexander Polakov char inqstring[64];
5322b2e3c5SAlexander Polakov char devname[SPECNAMELEN + 1];
5422b2e3c5SAlexander Polakov u_int bus;
5522b2e3c5SAlexander Polakov u_int target;
5622b2e3c5SAlexander Polakov };
5722b2e3c5SAlexander Polakov
5822b2e3c5SAlexander Polakov struct mpt_drive_list {
5922b2e3c5SAlexander Polakov int ndrives;
6022b2e3c5SAlexander Polakov CONFIG_PAGE_RAID_PHYS_DISK_0 *drives[0];
6122b2e3c5SAlexander Polakov };
6222b2e3c5SAlexander Polakov
6322b2e3c5SAlexander Polakov struct mptutil_command {
6422b2e3c5SAlexander Polakov const char *name;
6522b2e3c5SAlexander Polakov int (*handler)(int ac, char **av);
6622b2e3c5SAlexander Polakov };
6722b2e3c5SAlexander Polakov
6822b2e3c5SAlexander Polakov #define MPT_DATASET(name) mptutil_ ## name ## _table
6922b2e3c5SAlexander Polakov
7022b2e3c5SAlexander Polakov #define MPT_COMMAND(set, name, function) \
7122b2e3c5SAlexander Polakov static struct mptutil_command function ## _mptutil_command = \
7222b2e3c5SAlexander Polakov { #name, function }; \
7322b2e3c5SAlexander Polakov DATA_SET(MPT_DATASET(set), function ## _mptutil_command)
7422b2e3c5SAlexander Polakov
7522b2e3c5SAlexander Polakov #define MPT_TABLE(set, name) \
7622b2e3c5SAlexander Polakov SET_DECLARE(MPT_DATASET(name), struct mptutil_command); \
7722b2e3c5SAlexander Polakov \
7822b2e3c5SAlexander Polakov static int \
7922b2e3c5SAlexander Polakov mptutil_ ## name ## _table_handler(int ac, char **av) \
8022b2e3c5SAlexander Polakov { \
8122b2e3c5SAlexander Polakov return (mpt_table_handler(SET_BEGIN(MPT_DATASET(name)), \
8222b2e3c5SAlexander Polakov SET_LIMIT(MPT_DATASET(name)), ac, av)); \
8322b2e3c5SAlexander Polakov } \
8422b2e3c5SAlexander Polakov MPT_COMMAND(set, name, mptutil_ ## name ## _table_handler)
8522b2e3c5SAlexander Polakov
8622b2e3c5SAlexander Polakov extern int mpt_unit;
8722b2e3c5SAlexander Polakov
8822b2e3c5SAlexander Polakov #ifdef DEBUG
8922b2e3c5SAlexander Polakov void hexdump(const void *ptr, int length, const char *hdr, int flags);
9022b2e3c5SAlexander Polakov #define HD_COLUMN_MASK 0xff
9122b2e3c5SAlexander Polakov #define HD_DELIM_MASK 0xff00
9222b2e3c5SAlexander Polakov #define HD_OMIT_COUNT (1 << 16)
9322b2e3c5SAlexander Polakov #define HD_OMIT_HEX (1 << 17)
9422b2e3c5SAlexander Polakov #define HD_OMIT_CHARS (1 << 18)
9522b2e3c5SAlexander Polakov #endif
9622b2e3c5SAlexander Polakov
9722b2e3c5SAlexander Polakov int mpt_table_handler(struct mptutil_command **start,
9822b2e3c5SAlexander Polakov struct mptutil_command **end, int ac, char **av);
9922b2e3c5SAlexander Polakov int mpt_read_config_page_header(int fd, U8 PageType, U8 PageNumber,
10022b2e3c5SAlexander Polakov U32 PageAddress, CONFIG_PAGE_HEADER *header, U16 *IOCStatus);
10122b2e3c5SAlexander Polakov void *mpt_read_config_page(int fd, U8 PageType, U8 PageNumber,
10222b2e3c5SAlexander Polakov U32 PageAddress, U16 *IOCStatus);
10322b2e3c5SAlexander Polakov void *mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion,
10422b2e3c5SAlexander Polakov U8 PageNumber, U32 PageAddress, U16 *IOCStatus);
10522b2e3c5SAlexander Polakov int mpt_write_config_page(int fd, void *buf, U16 *IOCStatus);
10622b2e3c5SAlexander Polakov const char *mpt_ioc_status(U16 IOCStatus);
10722b2e3c5SAlexander Polakov int mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID,
10822b2e3c5SAlexander Polakov U8 PhysDiskNum, U32 ActionDataWord, void *buf, int len,
10922b2e3c5SAlexander Polakov RAID_VOL0_STATUS *VolumeStatus, U32 *ActionData, int datalen,
11022b2e3c5SAlexander Polakov U16 *IOCStatus, U16 *ActionStatus, int write);
11122b2e3c5SAlexander Polakov const char *mpt_raid_status(U16 ActionStatus);
11222b2e3c5SAlexander Polakov int mpt_open(int unit);
11322b2e3c5SAlexander Polakov const char *mpt_raid_level(U8 VolumeType);
11422b2e3c5SAlexander Polakov const char *mpt_volstate(U8 State);
11522b2e3c5SAlexander Polakov const char *mpt_pdstate(CONFIG_PAGE_RAID_PHYS_DISK_0 *info);
11622b2e3c5SAlexander Polakov const char *mpt_pd_inq_string(CONFIG_PAGE_RAID_PHYS_DISK_0 *pd_info);
11722b2e3c5SAlexander Polakov struct mpt_drive_list *mpt_pd_list(int fd);
11822b2e3c5SAlexander Polakov void mpt_free_pd_list(struct mpt_drive_list *list);
11922b2e3c5SAlexander Polakov int mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd);
12022b2e3c5SAlexander Polakov const char *mpt_volume_name(U8 VolumeBus, U8 VolumeID);
12122b2e3c5SAlexander Polakov int mpt_fetch_disks(int fd, int *ndisks,
12222b2e3c5SAlexander Polakov struct mpt_standalone_disk **disksp);
12322b2e3c5SAlexander Polakov int mpt_lock_volume(U8 VolumeBus, U8 VolumeID);
12422b2e3c5SAlexander Polakov int mpt_lookup_drive(struct mpt_drive_list *list, const char *drive,
12522b2e3c5SAlexander Polakov U8 *PhysDiskNum);
12622b2e3c5SAlexander Polakov int mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus,
12722b2e3c5SAlexander Polakov U8 *VolumeID);
12822b2e3c5SAlexander Polakov int mpt_rescan_bus(int bus, int id);
12922b2e3c5SAlexander Polakov
13022b2e3c5SAlexander Polakov static __inline void *
mpt_read_man_page(int fd,U8 PageNumber,U16 * IOCStatus)13122b2e3c5SAlexander Polakov mpt_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus)
13222b2e3c5SAlexander Polakov {
13322b2e3c5SAlexander Polakov
13422b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_MANUFACTURING,
13522b2e3c5SAlexander Polakov PageNumber, 0, IOCStatus));
13622b2e3c5SAlexander Polakov }
13722b2e3c5SAlexander Polakov
13822b2e3c5SAlexander Polakov static __inline void *
mpt_read_ioc_page(int fd,U8 PageNumber,U16 * IOCStatus)13922b2e3c5SAlexander Polakov mpt_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus)
14022b2e3c5SAlexander Polakov {
14122b2e3c5SAlexander Polakov
14222b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_IOC, PageNumber,
14322b2e3c5SAlexander Polakov 0, IOCStatus));
14422b2e3c5SAlexander Polakov }
14522b2e3c5SAlexander Polakov
14622b2e3c5SAlexander Polakov static __inline U32
mpt_vol_pageaddr(U8 VolumeBus,U8 VolumeID)14722b2e3c5SAlexander Polakov mpt_vol_pageaddr(U8 VolumeBus, U8 VolumeID)
14822b2e3c5SAlexander Polakov {
14922b2e3c5SAlexander Polakov
15022b2e3c5SAlexander Polakov return (VolumeBus << 8 | VolumeID);
15122b2e3c5SAlexander Polakov }
15222b2e3c5SAlexander Polakov
15322b2e3c5SAlexander Polakov static __inline CONFIG_PAGE_RAID_VOL_0 *
mpt_vol_info(int fd,U8 VolumeBus,U8 VolumeID,U16 * IOCStatus)15422b2e3c5SAlexander Polakov mpt_vol_info(int fd, U8 VolumeBus, U8 VolumeID, U16 *IOCStatus)
15522b2e3c5SAlexander Polakov {
15622b2e3c5SAlexander Polakov
15722b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0,
15822b2e3c5SAlexander Polakov mpt_vol_pageaddr(VolumeBus, VolumeID), IOCStatus));
15922b2e3c5SAlexander Polakov }
16022b2e3c5SAlexander Polakov
16122b2e3c5SAlexander Polakov static __inline CONFIG_PAGE_RAID_VOL_1 *
mpt_vol_names(int fd,U8 VolumeBus,U8 VolumeID,U16 * IOCStatus)16222b2e3c5SAlexander Polakov mpt_vol_names(int fd, U8 VolumeBus, U8 VolumeID, U16 *IOCStatus)
16322b2e3c5SAlexander Polakov {
16422b2e3c5SAlexander Polakov
16522b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 1,
16622b2e3c5SAlexander Polakov mpt_vol_pageaddr(VolumeBus, VolumeID), IOCStatus));
16722b2e3c5SAlexander Polakov }
16822b2e3c5SAlexander Polakov
16922b2e3c5SAlexander Polakov static __inline CONFIG_PAGE_RAID_PHYS_DISK_0 *
mpt_pd_info(int fd,U8 PhysDiskNum,U16 * IOCStatus)17022b2e3c5SAlexander Polakov mpt_pd_info(int fd, U8 PhysDiskNum, U16 *IOCStatus)
17122b2e3c5SAlexander Polakov {
17222b2e3c5SAlexander Polakov
17322b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, 0,
17422b2e3c5SAlexander Polakov PhysDiskNum, IOCStatus));
17522b2e3c5SAlexander Polakov }
17622b2e3c5SAlexander Polakov
17722b2e3c5SAlexander Polakov #endif /* !__MPTUTIL_H__ */
178