pvscsi.h revision 1.1 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