mpt_evt.c revision 196212
1196212Sscottl/*- 2196212Sscottl * Copyright (c) 2008 Yahoo!, Inc. 3196212Sscottl * All rights reserved. 4196212Sscottl * Written by: John Baldwin <jhb@FreeBSD.org> 5196212Sscottl * 6196212Sscottl * Redistribution and use in source and binary forms, with or without 7196212Sscottl * modification, are permitted provided that the following conditions 8196212Sscottl * are met: 9196212Sscottl * 1. Redistributions of source code must retain the above copyright 10196212Sscottl * notice, this list of conditions and the following disclaimer. 11196212Sscottl * 2. Redistributions in binary form must reproduce the above copyright 12196212Sscottl * notice, this list of conditions and the following disclaimer in the 13196212Sscottl * documentation and/or other materials provided with the distribution. 14196212Sscottl * 3. Neither the name of the author nor the names of any co-contributors 15196212Sscottl * may be used to endorse or promote products derived from this software 16196212Sscottl * without specific prior written permission. 17196212Sscottl * 18196212Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19196212Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20196212Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21196212Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22196212Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23196212Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24196212Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25196212Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26196212Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27196212Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28196212Sscottl * SUCH DAMAGE. 29196212Sscottl */ 30196212Sscottl 31196212Sscottl#include <sys/cdefs.h> 32196212Sscottl__RCSID("$FreeBSD: head/usr.sbin/mptutil/mpt_evt.c 196212 2009-08-14 13:13:12Z scottl $"); 33196212Sscottl 34196212Sscottl#include <sys/param.h> 35196212Sscottl#include <sys/errno.h> 36196212Sscottl#include <ctype.h> 37196212Sscottl#include <err.h> 38196212Sscottl#include <stdio.h> 39196212Sscottl#include <stdlib.h> 40196212Sscottl#include <unistd.h> 41196212Sscottl#include "mptutil.h" 42196212Sscottl 43196212Sscottlstatic CONFIG_PAGE_LOG_0 * 44196212Sscottlmpt_get_events(int fd, U16 *IOCStatus) 45196212Sscottl{ 46196212Sscottl 47196212Sscottl return (mpt_read_extended_config_page(fd, MPI_CONFIG_EXTPAGETYPE_LOG, 48196212Sscottl 0, 0, 0, IOCStatus)); 49196212Sscottl} 50196212Sscottl 51196212Sscottl/* 52196212Sscottl * 1 2 3 4 5 6 7 53196212Sscottl * 1234567890123456789012345678901234567890123456789012345678901234567890 54196212Sscottl * < ID> < time > <ty> <X XX XX XX XX XX XX XX XX XX XX XX XX XX |..............| 55196212Sscottl * ID Time Type Log Data 56196212Sscottl */ 57196212Sscottlstatic void 58196212Sscottlmpt_print_event(MPI_LOG_0_ENTRY *entry, int verbose) 59196212Sscottl{ 60196212Sscottl int i; 61196212Sscottl 62196212Sscottl printf("%5d %7ds %4x ", entry->LogSequence, entry->TimeStamp, 63196212Sscottl entry->LogEntryQualifier); 64196212Sscottl for (i = 0; i < 14; i++) 65196212Sscottl printf("%02x ", entry->LogData[i]); 66196212Sscottl printf("|"); 67196212Sscottl for (i = 0; i < 14; i++) 68196212Sscottl printf("%c", isprint(entry->LogData[i]) ? entry->LogData[i] : 69196212Sscottl '.'); 70196212Sscottl printf("|\n"); 71196212Sscottl printf(" "); 72196212Sscottl for (i = 0; i < 14; i++) 73196212Sscottl printf("%02x ", entry->LogData[i + 14]); 74196212Sscottl printf("|"); 75196212Sscottl for (i = 0; i < 14; i++) 76196212Sscottl printf("%c", isprint(entry->LogData[i + 14]) ? 77196212Sscottl entry->LogData[i + 14] : '.'); 78196212Sscottl printf("|\n"); 79196212Sscottl} 80196212Sscottl 81196212Sscottlstatic int 82196212Sscottlevent_compare(const void *first, const void *second) 83196212Sscottl{ 84196212Sscottl MPI_LOG_0_ENTRY * const *one; 85196212Sscottl MPI_LOG_0_ENTRY * const *two; 86196212Sscottl 87196212Sscottl one = first; 88196212Sscottl two = second; 89196212Sscottl return ((*one)->LogSequence - ((*two)->LogSequence)); 90196212Sscottl} 91196212Sscottl 92196212Sscottlstatic int 93196212Sscottlshow_events(int ac, char **av) 94196212Sscottl{ 95196212Sscottl CONFIG_PAGE_LOG_0 *log; 96196212Sscottl MPI_LOG_0_ENTRY **entries; 97196212Sscottl int ch, fd, i, num_events, verbose; 98196212Sscottl 99196212Sscottl fd = mpt_open(mpt_unit); 100196212Sscottl if (fd < 0) { 101196212Sscottl warn("mpt_open"); 102196212Sscottl return (errno); 103196212Sscottl } 104196212Sscottl 105196212Sscottl log = mpt_get_events(fd, NULL); 106196212Sscottl if (log == NULL) { 107196212Sscottl warn("Failed to get event log info"); 108196212Sscottl return (errno); 109196212Sscottl } 110196212Sscottl 111196212Sscottl /* Default settings. */ 112196212Sscottl verbose = 0; 113196212Sscottl 114196212Sscottl /* Parse any options. */ 115196212Sscottl optind = 1; 116196212Sscottl while ((ch = getopt(ac, av, "v")) != -1) { 117196212Sscottl switch (ch) { 118196212Sscottl case 'v': 119196212Sscottl verbose = 1; 120196212Sscottl break; 121196212Sscottl case '?': 122196212Sscottl default: 123196212Sscottl return (EINVAL); 124196212Sscottl } 125196212Sscottl } 126196212Sscottl ac -= optind; 127196212Sscottl av += optind; 128196212Sscottl 129196212Sscottl /* Build a list of valid entries and sort them by sequence. */ 130196212Sscottl entries = malloc(sizeof(MPI_LOG_0_ENTRY *) * log->NumLogEntries); 131196212Sscottl num_events = 0; 132196212Sscottl for (i = 0; i < log->NumLogEntries; i++) { 133196212Sscottl if (log->LogEntry[i].LogEntryQualifier == 134196212Sscottl MPI_LOG_0_ENTRY_QUAL_ENTRY_UNUSED) 135196212Sscottl continue; 136196212Sscottl entries[num_events] = &log->LogEntry[i]; 137196212Sscottl num_events++; 138196212Sscottl } 139196212Sscottl 140196212Sscottl qsort(entries, num_events, sizeof(MPI_LOG_0_ENTRY *), event_compare); 141196212Sscottl 142196212Sscottl if (num_events == 0) 143196212Sscottl printf("Event log is empty\n"); 144196212Sscottl else { 145196212Sscottl printf(" ID Time Type Log Data\n"); 146196212Sscottl for (i = 0; i < num_events; i++) 147196212Sscottl mpt_print_event(entries[i], verbose); 148196212Sscottl } 149196212Sscottl 150196212Sscottl free(entries); 151196212Sscottl close(fd); 152196212Sscottl 153196212Sscottl return (0); 154196212Sscottl} 155196212SscottlMPT_COMMAND(show, events, show_events); 156