1 1.1 skrll /*- 2 1.1 skrll * Copyright (c) 2018 VMware, Inc. 3 1.1 skrll * 4 1.1 skrll * SPDX-License-Identifier: (BSD-2-Clause OR GPL-2.0) 5 1.1 skrll * 6 1.1 skrll * $NetBSD: pvscsi.h,v 1.1 2025/08/04 20:03:12 skrll Exp $ 7 1.1 skrll */ 8 1.1 skrll 9 1.1 skrll /* 10 1.1 skrll 11 1.1 skrll These files are provided under a dual BSD-2 Clause/GPLv2 license. When 12 1.1 skrll using or redistributing this file, you may do so under either license. 13 1.1 skrll 14 1.1 skrll BSD-2 Clause License 15 1.1 skrll 16 1.1 skrll Copyright (c) 2018 VMware, Inc. 17 1.1 skrll 18 1.1 skrll Redistribution and use in source and binary forms, with or without 19 1.1 skrll modification, are permitted provided that the following conditions 20 1.1 skrll are met: 21 1.1 skrll 22 1.1 skrll * Redistributions of source code must retain the above copyright 23 1.1 skrll notice, this list of conditions and the following disclaimer. 24 1.1 skrll 25 1.1 skrll * Redistributions in binary form must reproduce the above copyright 26 1.1 skrll notice, this list of conditions and the following disclaimer in 27 1.1 skrll the documentation and/or other materials provided with the 28 1.1 skrll distribution. 29 1.1 skrll 30 1.1 skrll THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 1.1 skrll "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 1.1 skrll LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33 1.1 skrll A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34 1.1 skrll OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35 1.1 skrll SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36 1.1 skrll LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37 1.1 skrll DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38 1.1 skrll THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39 1.1 skrll (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40 1.1 skrll OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 1.1 skrll 42 1.1 skrll GPL License Summary 43 1.1 skrll 44 1.1 skrll Copyright (c) 2018 VMware, Inc. 45 1.1 skrll 46 1.1 skrll This program is free software; you can redistribute it and/or modify 47 1.1 skrll it under the terms of version 2 of the GNU General Public License as 48 1.1 skrll published by the Free Software Foundation. 49 1.1 skrll 50 1.1 skrll This program is distributed in the hope that it will be useful, but 51 1.1 skrll WITHOUT ANY WARRANTY; without even the implied warranty of 52 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 53 1.1 skrll General Public License for more details. 54 1.1 skrll 55 1.1 skrll You should have received a copy of the GNU General Public License 56 1.1 skrll along with this program; if not, write to the Free Software 57 1.1 skrll Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 58 1.1 skrll The full GNU General Public License is included in this distribution 59 1.1 skrll in the file called LICENSE.GPL. 60 1.1 skrll 61 1.1 skrll */ 62 1.1 skrll 63 1.1 skrll #ifndef _PVSCSI_H_ 64 1.1 skrll #define _PVSCSI_H_ 65 1.1 skrll 66 1.1 skrll #define MASK(v) ((1 << (v)) - 1) 67 1.1 skrll 68 1.1 skrll enum pvscsi_reg_offset { 69 1.1 skrll PVSCSI_REG_OFFSET_COMMAND = 0x0000, 70 1.1 skrll PVSCSI_REG_OFFSET_COMMAND_DATA = 0x0004, 71 1.1 skrll PVSCSI_REG_OFFSET_COMMAND_STATUS = 0x0008, 72 1.1 skrll PVSCSI_REG_OFFSET_LAST_STS_0 = 0x0100, 73 1.1 skrll PVSCSI_REG_OFFSET_LAST_STS_1 = 0x0104, 74 1.1 skrll PVSCSI_REG_OFFSET_LAST_STS_2 = 0x0108, 75 1.1 skrll PVSCSI_REG_OFFSET_LAST_STS_3 = 0x010c, 76 1.1 skrll PVSCSI_REG_OFFSET_INTR_STATUS = 0x100c, 77 1.1 skrll PVSCSI_REG_OFFSET_INTR_MASK = 0x2010, 78 1.1 skrll PVSCSI_REG_OFFSET_KICK_NON_RW_IO = 0x3014, 79 1.1 skrll PVSCSI_REG_OFFSET_DEBUG = 0x3018, 80 1.1 skrll PVSCSI_REG_OFFSET_KICK_RW_IO = 0x4018, 81 1.1 skrll }; 82 1.1 skrll 83 1.1 skrll enum pvscsi_commands { 84 1.1 skrll PVSCSI_CMD_FIRST = 0, 85 1.1 skrll 86 1.1 skrll PVSCSI_CMD_ADAPTER_RESET = 1, 87 1.1 skrll PVSCSI_CMD_ISSUE_SCSI = 2, 88 1.1 skrll PVSCSI_CMD_SETUP_RINGS = 3, 89 1.1 skrll PVSCSI_CMD_RESET_BUS = 4, 90 1.1 skrll PVSCSI_CMD_RESET_DEVICE = 5, 91 1.1 skrll PVSCSI_CMD_ABORT_CMD = 6, 92 1.1 skrll PVSCSI_CMD_CONFIG = 7, 93 1.1 skrll PVSCSI_CMD_SETUP_MSG_RING = 8, 94 1.1 skrll PVSCSI_CMD_DEVICE_UNPLUG = 9, 95 1.1 skrll PVSCSI_CMD_SETUP_REQCALLTHRESHOLD = 10, 96 1.1 skrll PVSCSI_CMD_GET_MAX_TARGETS = 11, 97 1.1 skrll 98 1.1 skrll PVSCSI_CMD_LAST = 12, 99 1.1 skrll }; 100 1.1 skrll 101 1.1 skrll struct pvscsi_cmd_desc_reset_device { 102 1.1 skrll uint32_t target; 103 1.1 skrll uint8_t lun[8]; 104 1.1 skrll }; 105 1.1 skrll 106 1.1 skrll struct pvscsi_cmd_desc_abort_cmd { 107 1.1 skrll uint64_t context; 108 1.1 skrll uint32_t target; 109 1.1 skrll uint32_t pad; 110 1.1 skrll }; 111 1.1 skrll 112 1.1 skrll #define PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 32 113 1.1 skrll #define PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 16 114 1.1 skrll 115 1.1 skrll struct pvscsi_cmd_desc_setup_rings { 116 1.1 skrll uint32_t req_ring_num_pages; 117 1.1 skrll uint32_t cmp_ring_num_pages; 118 1.1 skrll uint64_t rings_state_ppn; 119 1.1 skrll uint64_t req_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; 120 1.1 skrll uint64_t cmp_ring_ppns[PVSCSI_SETUP_RINGS_MAX_NUM_PAGES]; 121 1.1 skrll }; 122 1.1 skrll 123 1.1 skrll struct pvscsi_cmd_desc_setup_msg_ring { 124 1.1 skrll uint32_t num_pages; 125 1.1 skrll uint32_t pad_; 126 1.1 skrll uint64_t ring_ppns[PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES]; 127 1.1 skrll }; 128 1.1 skrll 129 1.1 skrll struct pvscsi_rings_state { 130 1.1 skrll uint32_t req_prod_idx; 131 1.1 skrll uint32_t req_cons_idx; 132 1.1 skrll uint32_t req_num_entries_log2; 133 1.1 skrll uint32_t cmp_prod_idx; 134 1.1 skrll uint32_t cmp_cons_idx; 135 1.1 skrll uint32_t cmp_num_entries_log2; 136 1.1 skrll uint32_t req_call_threshold; 137 1.1 skrll uint8_t _pad[100]; 138 1.1 skrll uint32_t msg_prod_idx; 139 1.1 skrll uint32_t msg_cons_idx; 140 1.1 skrll uint32_t msg_num_entries_log2; 141 1.1 skrll }; 142 1.1 skrll 143 1.1 skrll #define PVSCSI_FLAG_CMD_WITH_SG_LIST (1 << 0) 144 1.1 skrll #define PVSCSI_FLAG_CMD_OUT_OF_BAND_CDB (1 << 1) 145 1.1 skrll #define PVSCSI_FLAG_CMD_DIR_NONE (1 << 2) 146 1.1 skrll #define PVSCSI_FLAG_CMD_DIR_TOHOST (1 << 3) 147 1.1 skrll #define PVSCSI_FLAG_CMD_DIR_TODEVICE (1 << 4) 148 1.1 skrll 149 1.1 skrll #define PVSCSI_FLAG_RESERVED_MASK (~MASK(5)) 150 1.1 skrll 151 1.1 skrll #define PVSCSI_INTR_CMPL_0 (1 << 0) 152 1.1 skrll #define PVSCSI_INTR_CMPL_1 (1 << 1) 153 1.1 skrll #define PVSCSI_INTR_CMPL_MASK MASK(2) 154 1.1 skrll 155 1.1 skrll #define PVSCSI_INTR_MSG_0 (1 << 2) 156 1.1 skrll #define PVSCSI_INTR_MSG_1 (1 << 3) 157 1.1 skrll #define PVSCSI_INTR_MSG_MASK (MASK(2) << 2) 158 1.1 skrll 159 1.1 skrll #define PVSCSI_INTR_ALL_SUPPORTED MASK(4) 160 1.1 skrll 161 1.1 skrll struct pvscsi_ring_req_desc { 162 1.1 skrll uint64_t context; 163 1.1 skrll uint64_t data_addr; 164 1.1 skrll uint64_t data_len; 165 1.1 skrll uint64_t sense_addr; 166 1.1 skrll uint32_t sense_len; 167 1.1 skrll uint32_t flags; 168 1.1 skrll uint8_t cdb[16]; 169 1.1 skrll uint8_t cdb_len; 170 1.1 skrll uint8_t lun[8]; 171 1.1 skrll uint8_t tag; 172 1.1 skrll uint8_t bus; 173 1.1 skrll uint8_t target; 174 1.1 skrll uint16_t vcpu_hint; 175 1.1 skrll uint8_t unused[58]; 176 1.1 skrll }; 177 1.1 skrll 178 1.1 skrll CTASSERT(sizeof(struct pvscsi_ring_req_desc) == 128); 179 1.1 skrll 180 1.1 skrll struct pvscsi_ring_cmp_desc { 181 1.1 skrll uint64_t context; 182 1.1 skrll uint64_t data_len; 183 1.1 skrll uint32_t sense_len; 184 1.1 skrll uint16_t host_status; 185 1.1 skrll uint16_t scsi_status; 186 1.1 skrll uint32_t _pad[2]; 187 1.1 skrll }; 188 1.1 skrll 189 1.1 skrll CTASSERT(sizeof(struct pvscsi_ring_cmp_desc) == 32); 190 1.1 skrll 191 1.1 skrll #define PVSCSI_MAX_SG_ENTRIES_PER_SEGMENT 128 192 1.1 skrll #define PVSCSI_MAX_NUM_SG_SEGMENTS 128 193 1.1 skrll #define PVSCSI_SGE_FLAG_CHAIN_ELEMENT (1 << 0) 194 1.1 skrll 195 1.1 skrll struct pvscsi_sg_element { 196 1.1 skrll uint64_t addr; 197 1.1 skrll uint32_t length; 198 1.1 skrll uint32_t flags; 199 1.1 skrll }; 200 1.1 skrll 201 1.1 skrll enum pvscsi_msg_type { 202 1.1 skrll PVSCSI_MSG_DEV_ADDED = 0, 203 1.1 skrll PVSCSI_MSG_DEV_REMOVED = 1, 204 1.1 skrll PVSCSI_MSG_LAST = 2, 205 1.1 skrll }; 206 1.1 skrll 207 1.1 skrll struct pvscsi_ring_msg_desc { 208 1.1 skrll uint32_t type; 209 1.1 skrll uint32_t args[31]; 210 1.1 skrll }; 211 1.1 skrll 212 1.1 skrll struct pvscsi_ring_msg_dev_status_changed { 213 1.1 skrll uint32_t type; 214 1.1 skrll uint32_t bus; 215 1.1 skrll uint32_t target; 216 1.1 skrll uint8_t lun[8]; 217 1.1 skrll uint32_t pad[27]; 218 1.1 skrll }; 219 1.1 skrll 220 1.1 skrll struct pvscsi_cmd_desc_setup_req_call { 221 1.1 skrll uint32_t enable; 222 1.1 skrll }; 223 1.1 skrll 224 1.1 skrll #define PVSCSI_MAX_NUM_PAGES_REQ_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 225 1.1 skrll #define PVSCSI_MAX_NUM_PAGES_CMP_RING PVSCSI_SETUP_RINGS_MAX_NUM_PAGES 226 1.1 skrll #define PVSCSI_MAX_NUM_PAGES_MSG_RING PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES 227 1.1 skrll 228 1.1 skrll #define PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE \ 229 1.1 skrll (PAGE_SIZE / sizeof(struct pvscsi_ring_req_desc)) 230 1.1 skrll #define PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE \ 231 1.1 skrll (PAGE_SIZE / sizeof(struct pvscs_ring_cmp_desc)) 232 1.1 skrll #define PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE \ 233 1.1 skrll (PAGE_SIZE / sizeof(struct pvscsi_ring_msg_desc)) 234 1.1 skrll 235 1.1 skrll #define PVSCSI_MAX_REQ_QUEUE_DEPTH \ 236 1.1 skrll (PVSCSI_MAX_NUM_PAGES_REQ_RING * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE) 237 1.1 skrll #define PVSCSI_MAX_CMP_QUEUE_DEPTH \ 238 1.1 skrll (PVSCSI_MAX_NUM_PAGES_CMP_RING * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE) 239 1.1 skrll #define PVSCSI_MAX_QUEUE_DEPTH \ 240 1.1 skrll MAX(PVSCSI_MAX_REQ_QUEUE_DEPTH, PVSCSI_MAX_CMP_QUEUE_DEPTH) 241 1.1 skrll 242 1.1 skrll enum pvscsi_host_status { 243 1.1 skrll BTSTAT_SUCCESS = 0x00, 244 1.1 skrll BTSTAT_LINKED_COMMAND_COMPLETED = 0x0a, 245 1.1 skrll BTSTAT_LINKED_COMMAND_COMPLETED_WITH_FLAG = 0x0b, 246 1.1 skrll BTSTAT_DATA_UNDERRUN = 0x0c, 247 1.1 skrll BTSTAT_SELTIMEO = 0x11, 248 1.1 skrll BTSTAT_DATARUN = 0x12, 249 1.1 skrll BTSTAT_BUSFREE = 0x13, 250 1.1 skrll BTSTAT_INVPHASE = 0x14, 251 1.1 skrll BTSTAT_INVCODE = 0x15, 252 1.1 skrll BTSTAT_INVOPCODE = 0x16, 253 1.1 skrll BTSTAT_LUNMISMATCH = 0x17, 254 1.1 skrll BTSTAT_INVPARAM = 0x1a, 255 1.1 skrll BTSTAT_SENSFAILED = 0x1b, 256 1.1 skrll BTSTAT_TAGREJECT = 0x1c, 257 1.1 skrll BTSTAT_BADMSG = 0x1d, 258 1.1 skrll BTSTAT_HAHARDWARE = 0x20, 259 1.1 skrll BTSTAT_NORESPONSE = 0x21, 260 1.1 skrll BTSTAT_SENTRST = 0x22, 261 1.1 skrll BTSTAT_RECVRST = 0x23, 262 1.1 skrll BTSTAT_DISCONNECT = 0x24, 263 1.1 skrll BTSTAT_BUSRESET = 0x25, 264 1.1 skrll BTSTAT_ABORTQUEUE = 0x26, 265 1.1 skrll BTSTAT_HASOFTWARE = 0x27, 266 1.1 skrll BTSTAT_HATIMEOUT = 0x30, 267 1.1 skrll BTSTAT_SCSIPARITY = 0x34, 268 1.1 skrll }; 269 1.1 skrll 270 1.1 skrll #endif /* !_PVSCSI_H_ */ 271