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/cdefs.h> 3722b2e3c5SAlexander Polakov #include <sys/linker_set.h> 3822b2e3c5SAlexander Polakov 39*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi_type.h> 40*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi.h> 41*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi_cnfg.h> 42*92734026SAlexander Polakov #include <dev/disk/mpt/mpilib/mpi_raid.h> 43*92734026SAlexander Polakov 44*92734026SAlexander Polakov #define SPECNAMELEN 15 /* XXX: hidden under _KERNEL in <sys/conf.h> */ 4522b2e3c5SAlexander Polakov 4622b2e3c5SAlexander Polakov #define IOC_STATUS_SUCCESS(status) \ 4722b2e3c5SAlexander Polakov (((status) & MPI_IOCSTATUS_MASK) == MPI_IOCSTATUS_SUCCESS) 4822b2e3c5SAlexander Polakov 4922b2e3c5SAlexander Polakov struct mpt_query_disk { 5022b2e3c5SAlexander Polakov char devname[SPECNAMELEN + 1]; 5122b2e3c5SAlexander Polakov }; 5222b2e3c5SAlexander Polakov 5322b2e3c5SAlexander Polakov struct mpt_standalone_disk { 5422b2e3c5SAlexander Polakov uint64_t maxlba; 5522b2e3c5SAlexander Polakov char inqstring[64]; 5622b2e3c5SAlexander Polakov char devname[SPECNAMELEN + 1]; 5722b2e3c5SAlexander Polakov u_int bus; 5822b2e3c5SAlexander Polakov u_int target; 5922b2e3c5SAlexander Polakov }; 6022b2e3c5SAlexander Polakov 6122b2e3c5SAlexander Polakov struct mpt_drive_list { 6222b2e3c5SAlexander Polakov int ndrives; 6322b2e3c5SAlexander Polakov CONFIG_PAGE_RAID_PHYS_DISK_0 *drives[0]; 6422b2e3c5SAlexander Polakov }; 6522b2e3c5SAlexander Polakov 6622b2e3c5SAlexander Polakov struct mptutil_command { 6722b2e3c5SAlexander Polakov const char *name; 6822b2e3c5SAlexander Polakov int (*handler)(int ac, char **av); 6922b2e3c5SAlexander Polakov }; 7022b2e3c5SAlexander Polakov 7122b2e3c5SAlexander Polakov #define MPT_DATASET(name) mptutil_ ## name ## _table 7222b2e3c5SAlexander Polakov 7322b2e3c5SAlexander Polakov #define MPT_COMMAND(set, name, function) \ 7422b2e3c5SAlexander Polakov static struct mptutil_command function ## _mptutil_command = \ 7522b2e3c5SAlexander Polakov { #name, function }; \ 7622b2e3c5SAlexander Polakov DATA_SET(MPT_DATASET(set), function ## _mptutil_command) 7722b2e3c5SAlexander Polakov 7822b2e3c5SAlexander Polakov #define MPT_TABLE(set, name) \ 7922b2e3c5SAlexander Polakov SET_DECLARE(MPT_DATASET(name), struct mptutil_command); \ 8022b2e3c5SAlexander Polakov \ 8122b2e3c5SAlexander Polakov static int \ 8222b2e3c5SAlexander Polakov mptutil_ ## name ## _table_handler(int ac, char **av) \ 8322b2e3c5SAlexander Polakov { \ 8422b2e3c5SAlexander Polakov return (mpt_table_handler(SET_BEGIN(MPT_DATASET(name)), \ 8522b2e3c5SAlexander Polakov SET_LIMIT(MPT_DATASET(name)), ac, av)); \ 8622b2e3c5SAlexander Polakov } \ 8722b2e3c5SAlexander Polakov MPT_COMMAND(set, name, mptutil_ ## name ## _table_handler) 8822b2e3c5SAlexander Polakov 8922b2e3c5SAlexander Polakov extern int mpt_unit; 9022b2e3c5SAlexander Polakov 9122b2e3c5SAlexander Polakov #ifdef DEBUG 9222b2e3c5SAlexander Polakov void hexdump(const void *ptr, int length, const char *hdr, int flags); 9322b2e3c5SAlexander Polakov #define HD_COLUMN_MASK 0xff 9422b2e3c5SAlexander Polakov #define HD_DELIM_MASK 0xff00 9522b2e3c5SAlexander Polakov #define HD_OMIT_COUNT (1 << 16) 9622b2e3c5SAlexander Polakov #define HD_OMIT_HEX (1 << 17) 9722b2e3c5SAlexander Polakov #define HD_OMIT_CHARS (1 << 18) 9822b2e3c5SAlexander Polakov #endif 9922b2e3c5SAlexander Polakov 10022b2e3c5SAlexander Polakov int mpt_table_handler(struct mptutil_command **start, 10122b2e3c5SAlexander Polakov struct mptutil_command **end, int ac, char **av); 10222b2e3c5SAlexander Polakov int mpt_read_config_page_header(int fd, U8 PageType, U8 PageNumber, 10322b2e3c5SAlexander Polakov U32 PageAddress, CONFIG_PAGE_HEADER *header, U16 *IOCStatus); 10422b2e3c5SAlexander Polakov void *mpt_read_config_page(int fd, U8 PageType, U8 PageNumber, 10522b2e3c5SAlexander Polakov U32 PageAddress, U16 *IOCStatus); 10622b2e3c5SAlexander Polakov void *mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, 10722b2e3c5SAlexander Polakov U8 PageNumber, U32 PageAddress, U16 *IOCStatus); 10822b2e3c5SAlexander Polakov int mpt_write_config_page(int fd, void *buf, U16 *IOCStatus); 10922b2e3c5SAlexander Polakov const char *mpt_ioc_status(U16 IOCStatus); 11022b2e3c5SAlexander Polakov int mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, 11122b2e3c5SAlexander Polakov U8 PhysDiskNum, U32 ActionDataWord, void *buf, int len, 11222b2e3c5SAlexander Polakov RAID_VOL0_STATUS *VolumeStatus, U32 *ActionData, int datalen, 11322b2e3c5SAlexander Polakov U16 *IOCStatus, U16 *ActionStatus, int write); 11422b2e3c5SAlexander Polakov const char *mpt_raid_status(U16 ActionStatus); 11522b2e3c5SAlexander Polakov int mpt_open(int unit); 11622b2e3c5SAlexander Polakov const char *mpt_raid_level(U8 VolumeType); 11722b2e3c5SAlexander Polakov const char *mpt_volstate(U8 State); 11822b2e3c5SAlexander Polakov const char *mpt_pdstate(CONFIG_PAGE_RAID_PHYS_DISK_0 *info); 11922b2e3c5SAlexander Polakov const char *mpt_pd_inq_string(CONFIG_PAGE_RAID_PHYS_DISK_0 *pd_info); 12022b2e3c5SAlexander Polakov struct mpt_drive_list *mpt_pd_list(int fd); 12122b2e3c5SAlexander Polakov void mpt_free_pd_list(struct mpt_drive_list *list); 12222b2e3c5SAlexander Polakov int mpt_query_disk(U8 VolumeBus, U8 VolumeID, struct mpt_query_disk *qd); 12322b2e3c5SAlexander Polakov const char *mpt_volume_name(U8 VolumeBus, U8 VolumeID); 12422b2e3c5SAlexander Polakov int mpt_fetch_disks(int fd, int *ndisks, 12522b2e3c5SAlexander Polakov struct mpt_standalone_disk **disksp); 12622b2e3c5SAlexander Polakov int mpt_lock_volume(U8 VolumeBus, U8 VolumeID); 12722b2e3c5SAlexander Polakov int mpt_lookup_drive(struct mpt_drive_list *list, const char *drive, 12822b2e3c5SAlexander Polakov U8 *PhysDiskNum); 12922b2e3c5SAlexander Polakov int mpt_lookup_volume(int fd, const char *name, U8 *VolumeBus, 13022b2e3c5SAlexander Polakov U8 *VolumeID); 13122b2e3c5SAlexander Polakov int mpt_rescan_bus(int bus, int id); 13222b2e3c5SAlexander Polakov 13322b2e3c5SAlexander Polakov static __inline void * 13422b2e3c5SAlexander Polakov mpt_read_man_page(int fd, U8 PageNumber, U16 *IOCStatus) 13522b2e3c5SAlexander Polakov { 13622b2e3c5SAlexander Polakov 13722b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_MANUFACTURING, 13822b2e3c5SAlexander Polakov PageNumber, 0, IOCStatus)); 13922b2e3c5SAlexander Polakov } 14022b2e3c5SAlexander Polakov 14122b2e3c5SAlexander Polakov static __inline void * 14222b2e3c5SAlexander Polakov mpt_read_ioc_page(int fd, U8 PageNumber, U16 *IOCStatus) 14322b2e3c5SAlexander Polakov { 14422b2e3c5SAlexander Polakov 14522b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_IOC, PageNumber, 14622b2e3c5SAlexander Polakov 0, IOCStatus)); 14722b2e3c5SAlexander Polakov } 14822b2e3c5SAlexander Polakov 14922b2e3c5SAlexander Polakov static __inline U32 15022b2e3c5SAlexander Polakov mpt_vol_pageaddr(U8 VolumeBus, U8 VolumeID) 15122b2e3c5SAlexander Polakov { 15222b2e3c5SAlexander Polakov 15322b2e3c5SAlexander Polakov return (VolumeBus << 8 | VolumeID); 15422b2e3c5SAlexander Polakov } 15522b2e3c5SAlexander Polakov 15622b2e3c5SAlexander Polakov static __inline CONFIG_PAGE_RAID_VOL_0 * 15722b2e3c5SAlexander Polakov mpt_vol_info(int fd, U8 VolumeBus, U8 VolumeID, U16 *IOCStatus) 15822b2e3c5SAlexander Polakov { 15922b2e3c5SAlexander Polakov 16022b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0, 16122b2e3c5SAlexander Polakov mpt_vol_pageaddr(VolumeBus, VolumeID), IOCStatus)); 16222b2e3c5SAlexander Polakov } 16322b2e3c5SAlexander Polakov 16422b2e3c5SAlexander Polakov static __inline CONFIG_PAGE_RAID_VOL_1 * 16522b2e3c5SAlexander Polakov mpt_vol_names(int fd, U8 VolumeBus, U8 VolumeID, U16 *IOCStatus) 16622b2e3c5SAlexander Polakov { 16722b2e3c5SAlexander Polakov 16822b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 1, 16922b2e3c5SAlexander Polakov mpt_vol_pageaddr(VolumeBus, VolumeID), IOCStatus)); 17022b2e3c5SAlexander Polakov } 17122b2e3c5SAlexander Polakov 17222b2e3c5SAlexander Polakov static __inline CONFIG_PAGE_RAID_PHYS_DISK_0 * 17322b2e3c5SAlexander Polakov mpt_pd_info(int fd, U8 PhysDiskNum, U16 *IOCStatus) 17422b2e3c5SAlexander Polakov { 17522b2e3c5SAlexander Polakov 17622b2e3c5SAlexander Polakov return (mpt_read_config_page(fd, MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, 0, 17722b2e3c5SAlexander Polakov PhysDiskNum, IOCStatus)); 17822b2e3c5SAlexander Polakov } 17922b2e3c5SAlexander Polakov 18022b2e3c5SAlexander Polakov #endif /* !__MPTUTIL_H__ */ 181