1a9643ea8Slogwang /*- 2*22ce4affSfengbojiang * SPDX-License-Identifier: BSD-3-Clause 3*22ce4affSfengbojiang * 4a9643ea8Slogwang * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry. 5a9643ea8Slogwang * All rights reserved. 6a9643ea8Slogwang * 7a9643ea8Slogwang * Redistribution and use in source and binary forms, with or without 8a9643ea8Slogwang * modification, are permitted provided that the following conditions 9a9643ea8Slogwang * are met: 10a9643ea8Slogwang * 1. Redistributions of source code must retain the above copyright 11a9643ea8Slogwang * notice, this list of conditions and the following disclaimer. 12a9643ea8Slogwang * 2. Redistributions in binary form must reproduce the above copyright 13a9643ea8Slogwang * notice, this list of conditions and the following disclaimer in the 14a9643ea8Slogwang * documentation and/or other materials provided with the distribution. 15a9643ea8Slogwang * 3. The name of the author may not be used to endorse or promote products 16a9643ea8Slogwang * derived from this software without specific prior written permission. 17a9643ea8Slogwang * 18a9643ea8Slogwang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19a9643ea8Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20a9643ea8Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21a9643ea8Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22a9643ea8Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23a9643ea8Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24a9643ea8Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25a9643ea8Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26a9643ea8Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27a9643ea8Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28a9643ea8Slogwang * SUCH DAMAGE. 29a9643ea8Slogwang * 30a9643ea8Slogwang * $FreeBSD$ 31a9643ea8Slogwang */ 32a9643ea8Slogwang 33a9643ea8Slogwang #ifndef _DEVICESTAT_H 34a9643ea8Slogwang #define _DEVICESTAT_H 35a9643ea8Slogwang 36a9643ea8Slogwang #include <sys/queue.h> 37a9643ea8Slogwang #include <sys/time.h> 38a9643ea8Slogwang 39a9643ea8Slogwang /* 40a9643ea8Slogwang * XXX: Should really be SPECNAMELEN 41a9643ea8Slogwang */ 42a9643ea8Slogwang #define DEVSTAT_NAME_LEN 16 43a9643ea8Slogwang 44a9643ea8Slogwang /* 45a9643ea8Slogwang * device name for the mmap device 46a9643ea8Slogwang */ 47a9643ea8Slogwang #define DEVSTAT_DEVICE_NAME "devstat" 48a9643ea8Slogwang 49a9643ea8Slogwang /* 50a9643ea8Slogwang * ATTENTION: The devstat version below should be incremented any time a 51a9643ea8Slogwang * change is made in struct devstat, or any time a change is made in the 52a9643ea8Slogwang * enumerated types that struct devstat uses. (Only if those changes 53a9643ea8Slogwang * would require a recompile -- i.e. re-arranging the order of an 54a9643ea8Slogwang * enumerated type or something like that.) This version number is used by 55a9643ea8Slogwang * userland utilities to determine whether or not they are in sync with the 56a9643ea8Slogwang * kernel. 57a9643ea8Slogwang */ 58a9643ea8Slogwang #define DEVSTAT_VERSION 6 59a9643ea8Slogwang 60a9643ea8Slogwang /* 61a9643ea8Slogwang * These flags specify which statistics features are supported or not 62a9643ea8Slogwang * supported by a particular device. The default is all statistics are 63a9643ea8Slogwang * supported. 64a9643ea8Slogwang */ 65a9643ea8Slogwang typedef enum { 66a9643ea8Slogwang DEVSTAT_ALL_SUPPORTED = 0x00, 67a9643ea8Slogwang DEVSTAT_NO_BLOCKSIZE = 0x01, 68a9643ea8Slogwang DEVSTAT_NO_ORDERED_TAGS = 0x02, 69a9643ea8Slogwang DEVSTAT_BS_UNAVAILABLE = 0x04 70a9643ea8Slogwang } devstat_support_flags; 71a9643ea8Slogwang 72a9643ea8Slogwang typedef enum { 73a9643ea8Slogwang DEVSTAT_NO_DATA = 0x00, 74a9643ea8Slogwang DEVSTAT_READ = 0x01, 75a9643ea8Slogwang DEVSTAT_WRITE = 0x02, 76a9643ea8Slogwang DEVSTAT_FREE = 0x03 77a9643ea8Slogwang } devstat_trans_flags; 78a9643ea8Slogwang #define DEVSTAT_N_TRANS_FLAGS 4 79a9643ea8Slogwang 80a9643ea8Slogwang typedef enum { 81a9643ea8Slogwang DEVSTAT_TAG_SIMPLE = 0x00, 82a9643ea8Slogwang DEVSTAT_TAG_HEAD = 0x01, 83a9643ea8Slogwang DEVSTAT_TAG_ORDERED = 0x02, 84a9643ea8Slogwang DEVSTAT_TAG_NONE = 0x03 85a9643ea8Slogwang } devstat_tag_type; 86a9643ea8Slogwang 87a9643ea8Slogwang typedef enum { 88a9643ea8Slogwang DEVSTAT_PRIORITY_MIN = 0x000, 89a9643ea8Slogwang DEVSTAT_PRIORITY_OTHER = 0x020, 90a9643ea8Slogwang DEVSTAT_PRIORITY_PASS = 0x030, 91a9643ea8Slogwang DEVSTAT_PRIORITY_FD = 0x040, 92a9643ea8Slogwang DEVSTAT_PRIORITY_WFD = 0x050, 93a9643ea8Slogwang DEVSTAT_PRIORITY_TAPE = 0x060, 94a9643ea8Slogwang DEVSTAT_PRIORITY_CD = 0x090, 95a9643ea8Slogwang DEVSTAT_PRIORITY_DISK = 0x110, 96a9643ea8Slogwang DEVSTAT_PRIORITY_ARRAY = 0x120, 97a9643ea8Slogwang DEVSTAT_PRIORITY_MAX = 0xfff 98a9643ea8Slogwang } devstat_priority; 99a9643ea8Slogwang 100a9643ea8Slogwang /* 101a9643ea8Slogwang * These types are intended to aid statistics gathering/display programs. 102a9643ea8Slogwang * The first 13 types (up to the 'target' flag) are identical numerically 103a9643ea8Slogwang * to the SCSI device type numbers. The next 3 types designate the device 104a9643ea8Slogwang * interface. Currently the choices are IDE, SCSI, and 'other'. The last 105a9643ea8Slogwang * flag specifies whether or not the given device is a passthrough device 106a9643ea8Slogwang * or not. If it is a passthrough device, the lower 4 bits specify which 107a9643ea8Slogwang * type of physical device lies under the passthrough device, and the next 108a9643ea8Slogwang * 4 bits specify the interface. 109a9643ea8Slogwang */ 110a9643ea8Slogwang typedef enum { 111a9643ea8Slogwang DEVSTAT_TYPE_DIRECT = 0x000, 112a9643ea8Slogwang DEVSTAT_TYPE_SEQUENTIAL = 0x001, 113a9643ea8Slogwang DEVSTAT_TYPE_PRINTER = 0x002, 114a9643ea8Slogwang DEVSTAT_TYPE_PROCESSOR = 0x003, 115a9643ea8Slogwang DEVSTAT_TYPE_WORM = 0x004, 116a9643ea8Slogwang DEVSTAT_TYPE_CDROM = 0x005, 117a9643ea8Slogwang DEVSTAT_TYPE_SCANNER = 0x006, 118a9643ea8Slogwang DEVSTAT_TYPE_OPTICAL = 0x007, 119a9643ea8Slogwang DEVSTAT_TYPE_CHANGER = 0x008, 120a9643ea8Slogwang DEVSTAT_TYPE_COMM = 0x009, 121a9643ea8Slogwang DEVSTAT_TYPE_ASC0 = 0x00a, 122a9643ea8Slogwang DEVSTAT_TYPE_ASC1 = 0x00b, 123a9643ea8Slogwang DEVSTAT_TYPE_STORARRAY = 0x00c, 124a9643ea8Slogwang DEVSTAT_TYPE_ENCLOSURE = 0x00d, 125a9643ea8Slogwang DEVSTAT_TYPE_FLOPPY = 0x00e, 126a9643ea8Slogwang DEVSTAT_TYPE_MASK = 0x00f, 127a9643ea8Slogwang DEVSTAT_TYPE_IF_SCSI = 0x010, 128a9643ea8Slogwang DEVSTAT_TYPE_IF_IDE = 0x020, 129a9643ea8Slogwang DEVSTAT_TYPE_IF_OTHER = 0x030, 130a9643ea8Slogwang DEVSTAT_TYPE_IF_MASK = 0x0f0, 131a9643ea8Slogwang DEVSTAT_TYPE_PASS = 0x100 132a9643ea8Slogwang } devstat_type_flags; 133a9643ea8Slogwang 134a9643ea8Slogwang /* 135a9643ea8Slogwang * XXX: Next revision should add 136a9643ea8Slogwang * off_t offset[DEVSTAT_N_TRANS_FLAGS]; 137a9643ea8Slogwang * XXX: which should contain the offset of the last completed transfer. 138a9643ea8Slogwang */ 139a9643ea8Slogwang struct devstat { 140a9643ea8Slogwang /* Internal house-keeping fields */ 141a9643ea8Slogwang u_int sequence0; /* Update sequence# */ 142a9643ea8Slogwang int allocated; /* Allocated entry */ 143a9643ea8Slogwang u_int start_count; /* started ops */ 144a9643ea8Slogwang u_int end_count; /* completed ops */ 145a9643ea8Slogwang struct bintime busy_from; /* 146a9643ea8Slogwang * busy time unaccounted 147a9643ea8Slogwang * for since this time 148a9643ea8Slogwang */ 149a9643ea8Slogwang STAILQ_ENTRY(devstat) dev_links; 150a9643ea8Slogwang u_int32_t device_number; /* 151a9643ea8Slogwang * Devstat device 152a9643ea8Slogwang * number. 153a9643ea8Slogwang */ 154a9643ea8Slogwang char device_name[DEVSTAT_NAME_LEN]; 155a9643ea8Slogwang int unit_number; 156a9643ea8Slogwang u_int64_t bytes[DEVSTAT_N_TRANS_FLAGS]; 157a9643ea8Slogwang u_int64_t operations[DEVSTAT_N_TRANS_FLAGS]; 158a9643ea8Slogwang struct bintime duration[DEVSTAT_N_TRANS_FLAGS]; 159a9643ea8Slogwang struct bintime busy_time; 160a9643ea8Slogwang struct bintime creation_time; /* 161a9643ea8Slogwang * Time the device was 162a9643ea8Slogwang * created. 163a9643ea8Slogwang */ 164a9643ea8Slogwang u_int32_t block_size; /* Block size, bytes */ 165a9643ea8Slogwang u_int64_t tag_types[3]; /* 166a9643ea8Slogwang * The number of 167a9643ea8Slogwang * simple, ordered, 168a9643ea8Slogwang * and head of queue 169a9643ea8Slogwang * tags sent. 170a9643ea8Slogwang */ 171a9643ea8Slogwang devstat_support_flags flags; /* 172a9643ea8Slogwang * Which statistics 173a9643ea8Slogwang * are supported by a 174a9643ea8Slogwang * given device. 175a9643ea8Slogwang */ 176a9643ea8Slogwang devstat_type_flags device_type; /* Device type */ 177a9643ea8Slogwang devstat_priority priority; /* Controls list pos. */ 178a9643ea8Slogwang const void *id; /* 179a9643ea8Slogwang * Identification for 180a9643ea8Slogwang * GEOM nodes 181a9643ea8Slogwang */ 182a9643ea8Slogwang u_int sequence1; /* Update sequence# */ 183a9643ea8Slogwang }; 184a9643ea8Slogwang 185a9643ea8Slogwang STAILQ_HEAD(devstatlist, devstat); 186a9643ea8Slogwang 187a9643ea8Slogwang #ifdef _KERNEL 188a9643ea8Slogwang struct bio; 189a9643ea8Slogwang 190a9643ea8Slogwang struct devstat *devstat_new_entry(const void *dev_name, int unit_number, 191a9643ea8Slogwang u_int32_t block_size, 192a9643ea8Slogwang devstat_support_flags flags, 193a9643ea8Slogwang devstat_type_flags device_type, 194a9643ea8Slogwang devstat_priority priority); 195a9643ea8Slogwang 196a9643ea8Slogwang void devstat_remove_entry(struct devstat *ds); 197*22ce4affSfengbojiang void devstat_start_transaction(struct devstat *ds, const struct bintime *now); 198a9643ea8Slogwang void devstat_start_transaction_bio(struct devstat *ds, struct bio *bp); 199*22ce4affSfengbojiang void devstat_start_transaction_bio_t0(struct devstat *ds, struct bio *bp); 200a9643ea8Slogwang void devstat_end_transaction(struct devstat *ds, u_int32_t bytes, 201a9643ea8Slogwang devstat_tag_type tag_type, 202a9643ea8Slogwang devstat_trans_flags flags, 203*22ce4affSfengbojiang const struct bintime *now, 204*22ce4affSfengbojiang const struct bintime *then); 205*22ce4affSfengbojiang void devstat_end_transaction_bio(struct devstat *ds, const struct bio *bp); 206*22ce4affSfengbojiang void devstat_end_transaction_bio_bt(struct devstat *ds, const struct bio *bp, 207*22ce4affSfengbojiang const struct bintime *now); 208a9643ea8Slogwang #endif 209a9643ea8Slogwang 210a9643ea8Slogwang #endif /* _DEVICESTAT_H */ 211