xref: /haiku/src/add-ons/kernel/drivers/disk/nvme/libnvme/nvme_internal.h (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
1af4a03dfSAugustin Cavalier /*-
2af4a03dfSAugustin Cavalier  *   BSD LICENSE
3af4a03dfSAugustin Cavalier  *
4af4a03dfSAugustin Cavalier  *   Copyright (c) Intel Corporation. All rights reserved.
5af4a03dfSAugustin Cavalier  *   Copyright (c) 2017, Western Digital Corporation or its affiliates.
6af4a03dfSAugustin Cavalier  *
7af4a03dfSAugustin Cavalier  *   Redistribution and use in source and binary forms, with or without
8af4a03dfSAugustin Cavalier  *   modification, are permitted provided that the following conditions
9af4a03dfSAugustin Cavalier  *   are met:
10af4a03dfSAugustin Cavalier  *
11af4a03dfSAugustin Cavalier  *     * Redistributions of source code must retain the above copyright
12af4a03dfSAugustin Cavalier  *       notice, this list of conditions and the following disclaimer.
13af4a03dfSAugustin Cavalier  *     * Redistributions in binary form must reproduce the above copyright
14af4a03dfSAugustin Cavalier  *       notice, this list of conditions and the following disclaimer in
15af4a03dfSAugustin Cavalier  *       the documentation and/or other materials provided with the
16af4a03dfSAugustin Cavalier  *       distribution.
17af4a03dfSAugustin Cavalier  *     * Neither the name of Intel Corporation nor the names of its
18af4a03dfSAugustin Cavalier  *       contributors may be used to endorse or promote products derived
19af4a03dfSAugustin Cavalier  *       from this software without specific prior written permission.
20af4a03dfSAugustin Cavalier  *
21af4a03dfSAugustin Cavalier  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22af4a03dfSAugustin Cavalier  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23af4a03dfSAugustin Cavalier  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24af4a03dfSAugustin Cavalier  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25af4a03dfSAugustin Cavalier  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26af4a03dfSAugustin Cavalier  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27af4a03dfSAugustin Cavalier  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28af4a03dfSAugustin Cavalier  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29af4a03dfSAugustin Cavalier  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30af4a03dfSAugustin Cavalier  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31af4a03dfSAugustin Cavalier  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32af4a03dfSAugustin Cavalier  */
33af4a03dfSAugustin Cavalier 
34af4a03dfSAugustin Cavalier #ifndef __NVME_INTERNAL_H__
35af4a03dfSAugustin Cavalier #define __NVME_INTERNAL_H__
36af4a03dfSAugustin Cavalier 
37af4a03dfSAugustin Cavalier #include "nvme_common.h"
38af4a03dfSAugustin Cavalier #include "nvme_pci.h"
39af4a03dfSAugustin Cavalier #include "nvme_intel.h"
40af4a03dfSAugustin Cavalier #include "nvme_mem.h"
41af4a03dfSAugustin Cavalier 
42af4a03dfSAugustin Cavalier #ifndef __HAIKU__
43af4a03dfSAugustin Cavalier #include <pthread.h>
44af4a03dfSAugustin Cavalier #include <sys/user.h> /* PAGE_SIZE */
45af4a03dfSAugustin Cavalier #else
46af4a03dfSAugustin Cavalier #include "nvme_platform.h"
47af4a03dfSAugustin Cavalier #endif
48af4a03dfSAugustin Cavalier 
49af4a03dfSAugustin Cavalier /*
50af4a03dfSAugustin Cavalier  * List functions.
51af4a03dfSAugustin Cavalier  */
52af4a03dfSAugustin Cavalier #define	LIST_FOREACH_SAFE(var, head, field, tvar)			\
53af4a03dfSAugustin Cavalier 	for ((var) = LIST_FIRST((head));				\
54af4a03dfSAugustin Cavalier 	     (var) && ((tvar) = LIST_NEXT((var), field), 1);		\
55af4a03dfSAugustin Cavalier 	     (var) = (tvar))
56af4a03dfSAugustin Cavalier 
57af4a03dfSAugustin Cavalier /*
58af4a03dfSAugustin Cavalier  * Tail queue functions.
59af4a03dfSAugustin Cavalier  */
60af4a03dfSAugustin Cavalier #define	TAILQ_FOREACH_SAFE(var, head, field, tvar)			\
61af4a03dfSAugustin Cavalier 	for ((var) = TAILQ_FIRST((head));				\
62af4a03dfSAugustin Cavalier 	     (var) && ((tvar) = TAILQ_NEXT((var), field), 1);		\
63af4a03dfSAugustin Cavalier 	     (var) = (tvar))
64af4a03dfSAugustin Cavalier 
65af4a03dfSAugustin Cavalier #define INTEL_DC_P3X00_DEVID	0x09538086
66af4a03dfSAugustin Cavalier 
67af4a03dfSAugustin Cavalier #define NVME_TIMEOUT_INFINITE	UINT64_MAX
68af4a03dfSAugustin Cavalier 
69af4a03dfSAugustin Cavalier /*
70af4a03dfSAugustin Cavalier  * Some Intel devices support vendor-unique read latency log page even
71af4a03dfSAugustin Cavalier  * though the log page directory says otherwise.
72af4a03dfSAugustin Cavalier  */
73af4a03dfSAugustin Cavalier #define NVME_INTEL_QUIRK_READ_LATENCY   0x1
74af4a03dfSAugustin Cavalier 
75af4a03dfSAugustin Cavalier /*
76af4a03dfSAugustin Cavalier  * Some Intel devices support vendor-unique write latency log page even
77af4a03dfSAugustin Cavalier  * though the log page directory says otherwise.
78af4a03dfSAugustin Cavalier  */
79af4a03dfSAugustin Cavalier #define NVME_INTEL_QUIRK_WRITE_LATENCY  0x2
80af4a03dfSAugustin Cavalier 
81af4a03dfSAugustin Cavalier /*
82af4a03dfSAugustin Cavalier  * Some controllers need a delay before starting to check the device
83af4a03dfSAugustin Cavalier  * readiness, which is done by reading the controller status register rdy bit.
84af4a03dfSAugustin Cavalier  */
85af4a03dfSAugustin Cavalier #define NVME_QUIRK_DELAY_BEFORE_CHK_RDY	0x4
86af4a03dfSAugustin Cavalier 
87af4a03dfSAugustin Cavalier /*
88af4a03dfSAugustin Cavalier  * Some controllers need a delay once the controller status register rdy bit
89af4a03dfSAugustin Cavalier  * switches from 0 to 1.
90af4a03dfSAugustin Cavalier  */
91af4a03dfSAugustin Cavalier #define NVME_QUIRK_DELAY_AFTER_RDY	0x8
92af4a03dfSAugustin Cavalier 
93af4a03dfSAugustin Cavalier /*
94af4a03dfSAugustin Cavalier  * Queues may consist of a contiguous block of physical
95af4a03dfSAugustin Cavalier  * memory or optionally a non-contiguous set of physical
96af4a03dfSAugustin Cavalier  * memory pages (defined by a Physical Region Pages List)
97af4a03dfSAugustin Cavalier  */
98af4a03dfSAugustin Cavalier #define NVME_MAX_PRP_LIST_ENTRIES       (506)
99af4a03dfSAugustin Cavalier 
100af4a03dfSAugustin Cavalier /*
101af4a03dfSAugustin Cavalier  * For commands requiring more than 2 PRP entries, one PRP will be
102af4a03dfSAugustin Cavalier  * embedded in the command (prp1), and the rest of the PRP entries
103af4a03dfSAugustin Cavalier  * will be in a list pointed to by the command (prp2).  This means
104af4a03dfSAugustin Cavalier  * that real max number of PRP entries we support is 506+1, which
105af4a03dfSAugustin Cavalier  * results in a max xfer size of 506*PAGE_SIZE.
106af4a03dfSAugustin Cavalier  */
107af4a03dfSAugustin Cavalier #define NVME_MAX_XFER_SIZE	NVME_MAX_PRP_LIST_ENTRIES * PAGE_SIZE
108af4a03dfSAugustin Cavalier 
109af4a03dfSAugustin Cavalier #define NVME_ADMIN_TRACKERS	        (16)
110af4a03dfSAugustin Cavalier #define NVME_ADMIN_ENTRIES	        (128)
111af4a03dfSAugustin Cavalier 
112af4a03dfSAugustin Cavalier /*
113af4a03dfSAugustin Cavalier  * NVME_IO_ENTRIES defines the size of an I/O qpair's submission and completion
114af4a03dfSAugustin Cavalier  * queues, while NVME_IO_TRACKERS defines the maximum number of I/O that we
115af4a03dfSAugustin Cavalier  * will allow outstanding on an I/O qpair at any time. The only advantage in
116af4a03dfSAugustin Cavalier  * having IO_ENTRIES > IO_TRACKERS is for debugging purposes - when dumping
117af4a03dfSAugustin Cavalier  * the contents of the submission and completion queues, it will show a longer
118af4a03dfSAugustin Cavalier  * history of data.
119af4a03dfSAugustin Cavalier  */
120af4a03dfSAugustin Cavalier #define NVME_IO_ENTRIES		        (1024U)
121af4a03dfSAugustin Cavalier #define NVME_IO_TRACKERS	        (128U)
122af4a03dfSAugustin Cavalier #define NVME_IO_ENTRIES_VS_TRACKERS_RATIO (NVME_IO_ENTRIES / NVME_IO_TRACKERS)
123af4a03dfSAugustin Cavalier 
124af4a03dfSAugustin Cavalier /*
125af4a03dfSAugustin Cavalier  * NVME_MAX_SGL_DESCRIPTORS defines the maximum number of descriptors in one SGL
126af4a03dfSAugustin Cavalier  * segment.
127af4a03dfSAugustin Cavalier  */
128af4a03dfSAugustin Cavalier #define NVME_MAX_SGL_DESCRIPTORS	(253)
129af4a03dfSAugustin Cavalier 
130af4a03dfSAugustin Cavalier /*
131af4a03dfSAugustin Cavalier  * NVME_MAX_IO_ENTRIES is not defined, since it is specified in CC.MQES
132af4a03dfSAugustin Cavalier  * for each controller.
133af4a03dfSAugustin Cavalier  */
134af4a03dfSAugustin Cavalier 
135af4a03dfSAugustin Cavalier #define NVME_MAX_ASYNC_EVENTS	        (8)
136af4a03dfSAugustin Cavalier 
137af4a03dfSAugustin Cavalier /*
138af4a03dfSAugustin Cavalier  * NVME_MAX_IO_QUEUES in nvme_spec.h defines the 64K spec-limit, but this
139af4a03dfSAugustin Cavalier  * define specifies the maximum number of queues this driver will actually
140af4a03dfSAugustin Cavalier  * try to configure, if available.
141af4a03dfSAugustin Cavalier  */
142af4a03dfSAugustin Cavalier #define DEFAULT_MAX_IO_QUEUES		(1024)
143af4a03dfSAugustin Cavalier 
144af4a03dfSAugustin Cavalier /*
145af4a03dfSAugustin Cavalier  * Maximum of times a failed command can be retried.
146af4a03dfSAugustin Cavalier  */
147af4a03dfSAugustin Cavalier #define NVME_MAX_RETRY_COUNT		(3)
148af4a03dfSAugustin Cavalier 
149af4a03dfSAugustin Cavalier /*
150af4a03dfSAugustin Cavalier  * I/O queue type.
151af4a03dfSAugustin Cavalier  */
152af4a03dfSAugustin Cavalier enum nvme_io_queue_type {
153af4a03dfSAugustin Cavalier 
154af4a03dfSAugustin Cavalier 	NVME_IO_QTYPE_INVALID = 0,
155af4a03dfSAugustin Cavalier 	NVME_IO_SUBMISSION_QUEUE,
156af4a03dfSAugustin Cavalier 	NVME_IO_COMPLETION_QUEUE,
157af4a03dfSAugustin Cavalier };
158af4a03dfSAugustin Cavalier 
159af4a03dfSAugustin Cavalier enum nvme_payload_type {
160af4a03dfSAugustin Cavalier 
161af4a03dfSAugustin Cavalier 	NVME_PAYLOAD_TYPE_INVALID = 0,
162af4a03dfSAugustin Cavalier 
163af4a03dfSAugustin Cavalier 	/*
164af4a03dfSAugustin Cavalier 	 * nvme_request::u.payload.contig_buffer is valid for this request.
165af4a03dfSAugustin Cavalier 	 */
166af4a03dfSAugustin Cavalier 	NVME_PAYLOAD_TYPE_CONTIG,
167af4a03dfSAugustin Cavalier 
168af4a03dfSAugustin Cavalier 	/*
169af4a03dfSAugustin Cavalier 	 * nvme_request::u.sgl is valid for this request
170af4a03dfSAugustin Cavalier 	 */
171af4a03dfSAugustin Cavalier 	NVME_PAYLOAD_TYPE_SGL,
172af4a03dfSAugustin Cavalier };
173af4a03dfSAugustin Cavalier 
174af4a03dfSAugustin Cavalier /*
175af4a03dfSAugustin Cavalier  * Controller support flags.
176af4a03dfSAugustin Cavalier  */
177af4a03dfSAugustin Cavalier enum nvme_ctrlr_flags {
178af4a03dfSAugustin Cavalier 
179af4a03dfSAugustin Cavalier 	/*
180af4a03dfSAugustin Cavalier 	 * The SGL is supported.
181af4a03dfSAugustin Cavalier 	 */
182af4a03dfSAugustin Cavalier 	NVME_CTRLR_SGL_SUPPORTED = 0x1,
183af4a03dfSAugustin Cavalier 
184af4a03dfSAugustin Cavalier };
185af4a03dfSAugustin Cavalier 
186af4a03dfSAugustin Cavalier /*
187af4a03dfSAugustin Cavalier  * Descriptor for a request data payload.
188af4a03dfSAugustin Cavalier  *
189af4a03dfSAugustin Cavalier  * This struct is arranged so that it fits nicely in struct nvme_request.
190af4a03dfSAugustin Cavalier  */
191af4a03dfSAugustin Cavalier struct __attribute__((packed)) nvme_payload {
192af4a03dfSAugustin Cavalier 
193af4a03dfSAugustin Cavalier 	union {
194af4a03dfSAugustin Cavalier 		/*
195af4a03dfSAugustin Cavalier 		 * Virtual memory address of a single
196af4a03dfSAugustin Cavalier 		 * physically contiguous buffer
197af4a03dfSAugustin Cavalier 		 */
198af4a03dfSAugustin Cavalier 		void *contig;
199af4a03dfSAugustin Cavalier 
200af4a03dfSAugustin Cavalier 		/*
201af4a03dfSAugustin Cavalier 		 * Call back functions for retrieving physical
202af4a03dfSAugustin Cavalier 		 * addresses for scattered payloads.
203af4a03dfSAugustin Cavalier 		 */
204af4a03dfSAugustin Cavalier 		struct {
205af4a03dfSAugustin Cavalier 			nvme_req_reset_sgl_cb reset_sgl_fn;
206af4a03dfSAugustin Cavalier 			nvme_req_next_sge_cb next_sge_fn;
207af4a03dfSAugustin Cavalier 			void *cb_arg;
208af4a03dfSAugustin Cavalier 		} sgl;
209af4a03dfSAugustin Cavalier 	} u;
210af4a03dfSAugustin Cavalier 
211af4a03dfSAugustin Cavalier 	/*
212af4a03dfSAugustin Cavalier 	 * Virtual memory address of a single physically
213af4a03dfSAugustin Cavalier 	 * contiguous metadata buffer
214af4a03dfSAugustin Cavalier 	 */
215af4a03dfSAugustin Cavalier 	void *md;
216af4a03dfSAugustin Cavalier 
217af4a03dfSAugustin Cavalier 	/*
218af4a03dfSAugustin Cavalier 	 * Payload type.
219af4a03dfSAugustin Cavalier 	 */
220af4a03dfSAugustin Cavalier 	uint8_t type;
221af4a03dfSAugustin Cavalier 
222af4a03dfSAugustin Cavalier };
223af4a03dfSAugustin Cavalier 
224af4a03dfSAugustin Cavalier struct nvme_request {
225af4a03dfSAugustin Cavalier 
226af4a03dfSAugustin Cavalier 	/*
227af4a03dfSAugustin Cavalier 	 * NVMe command: must be aligned on 64B.
228af4a03dfSAugustin Cavalier 	 */
229af4a03dfSAugustin Cavalier 	struct nvme_cmd		         cmd;
230af4a03dfSAugustin Cavalier 
231af4a03dfSAugustin Cavalier 	/*
232af4a03dfSAugustin Cavalier 	 * Data payload for this request's command.
233af4a03dfSAugustin Cavalier 	 */
234af4a03dfSAugustin Cavalier 	struct nvme_payload              payload;
235af4a03dfSAugustin Cavalier 
236af4a03dfSAugustin Cavalier 	uint8_t			         retries;
237af4a03dfSAugustin Cavalier 
238af4a03dfSAugustin Cavalier 	/*
239af4a03dfSAugustin Cavalier 	 * Number of child requests still outstanding for this
240af4a03dfSAugustin Cavalier 	 * request which was split into multiple child requests.
241af4a03dfSAugustin Cavalier 	 */
242af4a03dfSAugustin Cavalier 	uint8_t			         child_reqs;
243af4a03dfSAugustin Cavalier 	uint32_t		         payload_size;
244af4a03dfSAugustin Cavalier 
245af4a03dfSAugustin Cavalier 	/*
246af4a03dfSAugustin Cavalier 	 * Offset in bytes from the beginning of payload for this request.
247af4a03dfSAugustin Cavalier 	 * This is used for I/O commands that are split into multiple requests.
248af4a03dfSAugustin Cavalier 	 */
249af4a03dfSAugustin Cavalier 	uint32_t	                 payload_offset;
250af4a03dfSAugustin Cavalier 	uint32_t		         md_offset;
251af4a03dfSAugustin Cavalier 
252af4a03dfSAugustin Cavalier 	nvme_cmd_cb		         cb_fn;
253af4a03dfSAugustin Cavalier 	void			         *cb_arg;
254af4a03dfSAugustin Cavalier 
255af4a03dfSAugustin Cavalier 	/*
256af4a03dfSAugustin Cavalier 	 * The following members should not be reordered with members
257af4a03dfSAugustin Cavalier 	 * above.  These members are only needed when splitting
258af4a03dfSAugustin Cavalier 	 * requests which is done rarely, and the driver is careful
259af4a03dfSAugustin Cavalier 	 * to not touch the following fields until a split operation is
260af4a03dfSAugustin Cavalier 	 * needed, to avoid touching an extra cacheline.
261af4a03dfSAugustin Cavalier 	 */
262af4a03dfSAugustin Cavalier 
263af4a03dfSAugustin Cavalier 	/*
264af4a03dfSAugustin Cavalier 	 * Points to the outstanding child requests for a parent request.
265af4a03dfSAugustin Cavalier 	 * Only valid if a request was split into multiple child
266af4a03dfSAugustin Cavalier 	 * requests, and is not initialized for non-split requests.
267af4a03dfSAugustin Cavalier 	 */
268af4a03dfSAugustin Cavalier 	TAILQ_HEAD(, nvme_request)	 children;
269af4a03dfSAugustin Cavalier 
270af4a03dfSAugustin Cavalier 	/*
271af4a03dfSAugustin Cavalier 	 * Linked-list pointers for a child request in its parent's list.
272af4a03dfSAugustin Cavalier 	 */
273af4a03dfSAugustin Cavalier 	TAILQ_ENTRY(nvme_request)	 child_tailq;
274af4a03dfSAugustin Cavalier 
275af4a03dfSAugustin Cavalier 	/*
276af4a03dfSAugustin Cavalier 	 * For queueing in qpair queued_req or free_req.
277af4a03dfSAugustin Cavalier 	 */
278af4a03dfSAugustin Cavalier 	struct nvme_qpair		 *qpair;
279af4a03dfSAugustin Cavalier 	STAILQ_ENTRY(nvme_request)	 stailq;
280af4a03dfSAugustin Cavalier 
281af4a03dfSAugustin Cavalier 	/*
282af4a03dfSAugustin Cavalier 	 * Points to a parent request if part of a split request,
283af4a03dfSAugustin Cavalier 	 * NULL otherwise.
284af4a03dfSAugustin Cavalier 	 */
285af4a03dfSAugustin Cavalier 	struct nvme_request		 *parent;
286af4a03dfSAugustin Cavalier 
287af4a03dfSAugustin Cavalier 	/*
288af4a03dfSAugustin Cavalier 	 * Completion status for a parent request.  Initialized to all 0's
289af4a03dfSAugustin Cavalier 	 * (SUCCESS) before child requests are submitted.  If a child
290af4a03dfSAugustin Cavalier 	 * request completes with error, the error status is copied here,
291af4a03dfSAugustin Cavalier 	 * to ensure that the parent request is also completed with error
292af4a03dfSAugustin Cavalier 	 * status once all child requests are completed.
293af4a03dfSAugustin Cavalier 	 */
294af4a03dfSAugustin Cavalier 	struct nvme_cpl		         parent_status;
295af4a03dfSAugustin Cavalier 
296af4a03dfSAugustin Cavalier } __attribute__((aligned(64)));
297af4a03dfSAugustin Cavalier 
298af4a03dfSAugustin Cavalier struct nvme_completion_poll_status {
299af4a03dfSAugustin Cavalier 	struct nvme_cpl		cpl;
300af4a03dfSAugustin Cavalier 	bool			done;
301af4a03dfSAugustin Cavalier };
302af4a03dfSAugustin Cavalier 
303af4a03dfSAugustin Cavalier struct nvme_async_event_request {
304af4a03dfSAugustin Cavalier 	struct nvme_ctrlr	*ctrlr;
305af4a03dfSAugustin Cavalier 	struct nvme_request	*req;
306af4a03dfSAugustin Cavalier 	struct nvme_cpl		cpl;
307af4a03dfSAugustin Cavalier };
308af4a03dfSAugustin Cavalier 
309af4a03dfSAugustin Cavalier struct nvme_tracker {
310af4a03dfSAugustin Cavalier 
311af4a03dfSAugustin Cavalier 	LIST_ENTRY(nvme_tracker)	list;
312af4a03dfSAugustin Cavalier 
313af4a03dfSAugustin Cavalier 	struct nvme_request		*req;
314*1bcecb98SAugustin Cavalier #if INTPTR_MAX == INT32_MAX
315*1bcecb98SAugustin Cavalier 	int32_t __pad[3];
316*1bcecb98SAugustin Cavalier #elif !defined(INTPTR_MAX)
317*1bcecb98SAugustin Cavalier #	error Need definition of INTPTR_MAX!
318*1bcecb98SAugustin Cavalier #endif
319*1bcecb98SAugustin Cavalier 
320af4a03dfSAugustin Cavalier 	uint16_t			cid;
321af4a03dfSAugustin Cavalier 
322af4a03dfSAugustin Cavalier 	uint16_t			rsvd1: 15;
323af4a03dfSAugustin Cavalier 	uint16_t			active: 1;
324af4a03dfSAugustin Cavalier 
325af4a03dfSAugustin Cavalier 	uint32_t			rsvd2;
326af4a03dfSAugustin Cavalier 
327af4a03dfSAugustin Cavalier 	uint64_t			prp_sgl_bus_addr;
328af4a03dfSAugustin Cavalier 
329af4a03dfSAugustin Cavalier 	union {
330af4a03dfSAugustin Cavalier 		uint64_t			prp[NVME_MAX_PRP_LIST_ENTRIES];
331af4a03dfSAugustin Cavalier 		struct nvme_sgl_descriptor	sgl[NVME_MAX_SGL_DESCRIPTORS];
332af4a03dfSAugustin Cavalier 	} u;
333af4a03dfSAugustin Cavalier 
334af4a03dfSAugustin Cavalier 	uint64_t			rsvd3;
335af4a03dfSAugustin Cavalier };
336af4a03dfSAugustin Cavalier 
337af4a03dfSAugustin Cavalier /*
338af4a03dfSAugustin Cavalier  * struct nvme_tracker must be exactly 4K so that the prp[] array does not
339af4a03dfSAugustin Cavalier  * cross a page boundery and so that there is no padding required to meet
340af4a03dfSAugustin Cavalier  * alignment requirements.
341af4a03dfSAugustin Cavalier  */
342af4a03dfSAugustin Cavalier nvme_static_assert(sizeof(struct nvme_tracker) == 4096,
343af4a03dfSAugustin Cavalier 		   "nvme_tracker is not 4K");
344af4a03dfSAugustin Cavalier nvme_static_assert((offsetof(struct nvme_tracker, u.sgl) & 7) == 0,
345af4a03dfSAugustin Cavalier 		   "SGL must be Qword aligned");
346af4a03dfSAugustin Cavalier 
347af4a03dfSAugustin Cavalier struct nvme_qpair {
348625dc38aSAugustin Cavalier 	/*
349625dc38aSAugustin Cavalier 	 * Guards access to this structure.
350625dc38aSAugustin Cavalier 	 */
351625dc38aSAugustin Cavalier 	pthread_mutex_t				lock;
352af4a03dfSAugustin Cavalier 
353af4a03dfSAugustin Cavalier 	volatile uint32_t	        *sq_tdbl;
354af4a03dfSAugustin Cavalier 	volatile uint32_t	        *cq_hdbl;
355af4a03dfSAugustin Cavalier 
356af4a03dfSAugustin Cavalier 	/*
357af4a03dfSAugustin Cavalier 	 * Submission queue
358af4a03dfSAugustin Cavalier 	 */
359af4a03dfSAugustin Cavalier 	struct nvme_cmd		        *cmd;
360af4a03dfSAugustin Cavalier 
361af4a03dfSAugustin Cavalier 	/*
362af4a03dfSAugustin Cavalier 	 * Completion queue
363af4a03dfSAugustin Cavalier 	 */
364af4a03dfSAugustin Cavalier 	struct nvme_cpl		        *cpl;
365af4a03dfSAugustin Cavalier 
366af4a03dfSAugustin Cavalier 	LIST_HEAD(, nvme_tracker)	free_tr;
367af4a03dfSAugustin Cavalier 	LIST_HEAD(, nvme_tracker)	outstanding_tr;
368af4a03dfSAugustin Cavalier 
369af4a03dfSAugustin Cavalier 	/*
370af4a03dfSAugustin Cavalier 	 * Array of trackers indexed by command ID.
371af4a03dfSAugustin Cavalier 	 */
372af4a03dfSAugustin Cavalier 	uint16_t			trackers;
373af4a03dfSAugustin Cavalier 	struct nvme_tracker		*tr;
374af4a03dfSAugustin Cavalier 
375af4a03dfSAugustin Cavalier 	struct nvme_request		*reqs;
376af4a03dfSAugustin Cavalier 	unsigned int			num_reqs;
377af4a03dfSAugustin Cavalier 	STAILQ_HEAD(, nvme_request)	free_req;
378af4a03dfSAugustin Cavalier 	STAILQ_HEAD(, nvme_request)	queued_req;
379af4a03dfSAugustin Cavalier 
380af4a03dfSAugustin Cavalier 	uint16_t			id;
381af4a03dfSAugustin Cavalier 
382af4a03dfSAugustin Cavalier 	uint16_t			entries;
383af4a03dfSAugustin Cavalier 	uint16_t			sq_tail;
384af4a03dfSAugustin Cavalier 	uint16_t			cq_head;
385af4a03dfSAugustin Cavalier 
386af4a03dfSAugustin Cavalier 	uint8_t				phase;
387af4a03dfSAugustin Cavalier 
388af4a03dfSAugustin Cavalier 	bool				enabled;
389af4a03dfSAugustin Cavalier 	bool				sq_in_cmb;
390af4a03dfSAugustin Cavalier 
391af4a03dfSAugustin Cavalier 	/*
392af4a03dfSAugustin Cavalier 	 * Fields below this point should not be touched on the
393af4a03dfSAugustin Cavalier 	 * normal I/O happy path.
394af4a03dfSAugustin Cavalier 	 */
395af4a03dfSAugustin Cavalier 
396af4a03dfSAugustin Cavalier 	uint8_t				qprio;
397af4a03dfSAugustin Cavalier 
398af4a03dfSAugustin Cavalier 	struct nvme_ctrlr		*ctrlr;
399af4a03dfSAugustin Cavalier 
400af4a03dfSAugustin Cavalier 	/* List entry for nvme_ctrlr::free_io_qpairs and active_io_qpairs */
401af4a03dfSAugustin Cavalier 	TAILQ_ENTRY(nvme_qpair)		tailq;
402af4a03dfSAugustin Cavalier 
403af4a03dfSAugustin Cavalier 	phys_addr_t			cmd_bus_addr;
404af4a03dfSAugustin Cavalier 	phys_addr_t			cpl_bus_addr;
405af4a03dfSAugustin Cavalier };
406af4a03dfSAugustin Cavalier 
407af4a03dfSAugustin Cavalier struct nvme_ns {
408af4a03dfSAugustin Cavalier 
409af4a03dfSAugustin Cavalier 	struct nvme_ctrlr		*ctrlr;
410af4a03dfSAugustin Cavalier 
411af4a03dfSAugustin Cavalier 	uint32_t			stripe_size;
412af4a03dfSAugustin Cavalier 	uint32_t			sector_size;
413af4a03dfSAugustin Cavalier 
414af4a03dfSAugustin Cavalier 	uint32_t			md_size;
415af4a03dfSAugustin Cavalier 	uint32_t			pi_type;
416af4a03dfSAugustin Cavalier 
417af4a03dfSAugustin Cavalier 	uint32_t			sectors_per_max_io;
418af4a03dfSAugustin Cavalier 	uint32_t			sectors_per_stripe;
419af4a03dfSAugustin Cavalier 
420af4a03dfSAugustin Cavalier 	uint16_t			id;
421af4a03dfSAugustin Cavalier 	uint16_t			flags;
422af4a03dfSAugustin Cavalier 
423af4a03dfSAugustin Cavalier 	int				open_count;
424af4a03dfSAugustin Cavalier 
425af4a03dfSAugustin Cavalier };
426af4a03dfSAugustin Cavalier 
427af4a03dfSAugustin Cavalier /*
428af4a03dfSAugustin Cavalier  * State of struct nvme_ctrlr (in particular, during initialization).
429af4a03dfSAugustin Cavalier  */
430af4a03dfSAugustin Cavalier enum nvme_ctrlr_state {
431af4a03dfSAugustin Cavalier 
432af4a03dfSAugustin Cavalier 	/*
433af4a03dfSAugustin Cavalier 	 * Controller has not been initialized yet.
434af4a03dfSAugustin Cavalier 	 */
435af4a03dfSAugustin Cavalier 	NVME_CTRLR_STATE_INIT = 0,
436af4a03dfSAugustin Cavalier 
437af4a03dfSAugustin Cavalier 	/*
438af4a03dfSAugustin Cavalier 	 * Waiting for CSTS.RDY to transition from 0 to 1
439af4a03dfSAugustin Cavalier 	 * so that CC.EN may be set to 0.
440af4a03dfSAugustin Cavalier 	 */
441af4a03dfSAugustin Cavalier 	NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_1,
442af4a03dfSAugustin Cavalier 
443af4a03dfSAugustin Cavalier 	/*
444af4a03dfSAugustin Cavalier 	 * Waiting for CSTS.RDY to transition from 1 to 0
445af4a03dfSAugustin Cavalier 	 * so that CC.EN may be set to 1.
446af4a03dfSAugustin Cavalier 	 */
447af4a03dfSAugustin Cavalier 	NVME_CTRLR_STATE_DISABLE_WAIT_FOR_READY_0,
448af4a03dfSAugustin Cavalier 
449af4a03dfSAugustin Cavalier 	/*
450af4a03dfSAugustin Cavalier 	 * Waiting for CSTS.RDY to transition from 0 to 1
451af4a03dfSAugustin Cavalier 	 * after enabling the controller.
452af4a03dfSAugustin Cavalier 	 */
453af4a03dfSAugustin Cavalier 	NVME_CTRLR_STATE_ENABLE_WAIT_FOR_READY_1,
454af4a03dfSAugustin Cavalier 
455af4a03dfSAugustin Cavalier 	/*
456af4a03dfSAugustin Cavalier 	 * Controller initialization has completed and
457af4a03dfSAugustin Cavalier 	 * the controller is ready.
458af4a03dfSAugustin Cavalier 	 */
459af4a03dfSAugustin Cavalier 	NVME_CTRLR_STATE_READY
460af4a03dfSAugustin Cavalier };
461af4a03dfSAugustin Cavalier 
462af4a03dfSAugustin Cavalier /*
463af4a03dfSAugustin Cavalier  * One of these per allocated PCI device.
464af4a03dfSAugustin Cavalier  */
465af4a03dfSAugustin Cavalier struct nvme_ctrlr {
466af4a03dfSAugustin Cavalier 
467af4a03dfSAugustin Cavalier 	/*
468af4a03dfSAugustin Cavalier 	 * NVMe MMIO register space.
469af4a03dfSAugustin Cavalier 	 */
470af4a03dfSAugustin Cavalier 	volatile struct nvme_registers	*regs;
471af4a03dfSAugustin Cavalier 
472af4a03dfSAugustin Cavalier 	/*
473af4a03dfSAugustin Cavalier 	 * Array of I/O queue pairs.
474af4a03dfSAugustin Cavalier 	 */
475af4a03dfSAugustin Cavalier 	struct nvme_qpair		*ioq;
476af4a03dfSAugustin Cavalier 
477af4a03dfSAugustin Cavalier 	/*
478af4a03dfSAugustin Cavalier 	 * Size of the array of I/O queue pairs.
479af4a03dfSAugustin Cavalier 	 */
480af4a03dfSAugustin Cavalier 	unsigned int			io_queues;
481af4a03dfSAugustin Cavalier 
482af4a03dfSAugustin Cavalier 	/*
483af4a03dfSAugustin Cavalier 	 * Maximum I/O queue pairs.
484af4a03dfSAugustin Cavalier 	 */
485af4a03dfSAugustin Cavalier 	unsigned int			max_io_queues;
486af4a03dfSAugustin Cavalier 
487af4a03dfSAugustin Cavalier 	/*
488af4a03dfSAugustin Cavalier 	 * Number of I/O queue pairs enabled
489af4a03dfSAugustin Cavalier 	 */
490af4a03dfSAugustin Cavalier 	unsigned int			enabled_io_qpairs;
491af4a03dfSAugustin Cavalier 
492af4a03dfSAugustin Cavalier 	/*
493af4a03dfSAugustin Cavalier 	 * Maximum entries for I/O qpairs
494af4a03dfSAugustin Cavalier 	 */
495af4a03dfSAugustin Cavalier 	unsigned int			io_qpairs_max_entries;
496af4a03dfSAugustin Cavalier 
497af4a03dfSAugustin Cavalier 	/*
498af4a03dfSAugustin Cavalier 	 * Array of namespace IDs.
499af4a03dfSAugustin Cavalier 	 */
500af4a03dfSAugustin Cavalier 	unsigned int			nr_ns;
501af4a03dfSAugustin Cavalier 	struct nvme_ns		        *ns;
502af4a03dfSAugustin Cavalier 
503af4a03dfSAugustin Cavalier 	/*
504af4a03dfSAugustin Cavalier 	 * Controller state.
505af4a03dfSAugustin Cavalier 	 */
506af4a03dfSAugustin Cavalier 	bool				resetting;
507af4a03dfSAugustin Cavalier 	bool				failed;
508af4a03dfSAugustin Cavalier 
509af4a03dfSAugustin Cavalier 	/*
510af4a03dfSAugustin Cavalier 	 * Controller support flags.
511af4a03dfSAugustin Cavalier 	 */
512af4a03dfSAugustin Cavalier 	uint64_t			flags;
513af4a03dfSAugustin Cavalier 
514af4a03dfSAugustin Cavalier 	/*
515af4a03dfSAugustin Cavalier 	 * Cold data (not accessed in normal I/O path) is after this point.
516af4a03dfSAugustin Cavalier 	 */
517af4a03dfSAugustin Cavalier 	enum nvme_ctrlr_state		state;
518af4a03dfSAugustin Cavalier 	uint64_t			state_timeout_ms;
519af4a03dfSAugustin Cavalier 
520af4a03dfSAugustin Cavalier 	/*
521af4a03dfSAugustin Cavalier 	 * All the log pages supported.
522af4a03dfSAugustin Cavalier 	 */
523af4a03dfSAugustin Cavalier 	bool				log_page_supported[256];
524af4a03dfSAugustin Cavalier 
525af4a03dfSAugustin Cavalier 	/*
526af4a03dfSAugustin Cavalier 	 * All the features supported.
527af4a03dfSAugustin Cavalier 	 */
528af4a03dfSAugustin Cavalier 	bool				feature_supported[256];
529af4a03dfSAugustin Cavalier 
530af4a03dfSAugustin Cavalier 	/*
531af4a03dfSAugustin Cavalier 	 * Associated PCI device information.
532af4a03dfSAugustin Cavalier 	 */
533af4a03dfSAugustin Cavalier 	struct pci_device		*pci_dev;
534af4a03dfSAugustin Cavalier 
535af4a03dfSAugustin Cavalier 	/*
536af4a03dfSAugustin Cavalier 	 * Maximum i/o size in bytes.
537af4a03dfSAugustin Cavalier 	 */
538af4a03dfSAugustin Cavalier 	uint32_t			max_xfer_size;
539af4a03dfSAugustin Cavalier 
540af4a03dfSAugustin Cavalier 	/*
541af4a03dfSAugustin Cavalier 	 * Minimum page size supported by this controller in bytes.
542af4a03dfSAugustin Cavalier 	 */
543af4a03dfSAugustin Cavalier 	uint32_t			min_page_size;
544af4a03dfSAugustin Cavalier 
545af4a03dfSAugustin Cavalier 	/*
546af4a03dfSAugustin Cavalier 	 * Stride in uint32_t units between doorbell registers
547af4a03dfSAugustin Cavalier 	 * (1 = 4 bytes, 2 = 8 bytes, ...).
548af4a03dfSAugustin Cavalier 	 */
549af4a03dfSAugustin Cavalier 	uint32_t			doorbell_stride_u32;
550af4a03dfSAugustin Cavalier 
551af4a03dfSAugustin Cavalier 	uint32_t			num_aers;
552af4a03dfSAugustin Cavalier 	struct nvme_async_event_request	aer[NVME_MAX_ASYNC_EVENTS];
553af4a03dfSAugustin Cavalier 	nvme_aer_cb		        aer_cb_fn;
554af4a03dfSAugustin Cavalier 	void				*aer_cb_arg;
555af4a03dfSAugustin Cavalier 
556af4a03dfSAugustin Cavalier 	/*
557af4a03dfSAugustin Cavalier 	 * Admin queue pair.
558af4a03dfSAugustin Cavalier 	 */
559af4a03dfSAugustin Cavalier 	struct nvme_qpair		adminq;
560af4a03dfSAugustin Cavalier 
561af4a03dfSAugustin Cavalier 	/*
562625dc38aSAugustin Cavalier 	 * Guards access to the controller itself.
563625dc38aSAugustin Cavalier 	 */
564625dc38aSAugustin Cavalier 	pthread_mutex_t			lock;
565625dc38aSAugustin Cavalier 
566625dc38aSAugustin Cavalier 	/*
567af4a03dfSAugustin Cavalier 	 * Identify Controller data.
568af4a03dfSAugustin Cavalier 	 */
569af4a03dfSAugustin Cavalier 	struct nvme_ctrlr_data		cdata;
570af4a03dfSAugustin Cavalier 
571af4a03dfSAugustin Cavalier 	/*
572af4a03dfSAugustin Cavalier 	 * Array of Identify Namespace data.
573af4a03dfSAugustin Cavalier 	 * Stored separately from ns since nsdata should
574af4a03dfSAugustin Cavalier 	 * not normally be accessed during I/O.
575af4a03dfSAugustin Cavalier 	 */
576af4a03dfSAugustin Cavalier 	struct nvme_ns_data	        *nsdata;
577af4a03dfSAugustin Cavalier 
578af4a03dfSAugustin Cavalier 	TAILQ_HEAD(, nvme_qpair)	free_io_qpairs;
579af4a03dfSAugustin Cavalier 	TAILQ_HEAD(, nvme_qpair)	active_io_qpairs;
580af4a03dfSAugustin Cavalier 
581af4a03dfSAugustin Cavalier 	/*
582af4a03dfSAugustin Cavalier 	 * Controller option set on open.
583af4a03dfSAugustin Cavalier 	 */
584af4a03dfSAugustin Cavalier 	struct nvme_ctrlr_opts		opts;
585af4a03dfSAugustin Cavalier 
586af4a03dfSAugustin Cavalier 	/*
587af4a03dfSAugustin Cavalier 	 * BAR mapping address which contains controller memory buffer.
588af4a03dfSAugustin Cavalier 	 */
589af4a03dfSAugustin Cavalier 	void				*cmb_bar_virt_addr;
590af4a03dfSAugustin Cavalier 
591af4a03dfSAugustin Cavalier 	/*
592af4a03dfSAugustin Cavalier 	 * BAR physical address which contains controller memory buffer.
593af4a03dfSAugustin Cavalier 	 */
594af4a03dfSAugustin Cavalier 	uint64_t			cmb_bar_phys_addr;
595af4a03dfSAugustin Cavalier 
596af4a03dfSAugustin Cavalier 	/*
597af4a03dfSAugustin Cavalier 	 * Controller memory buffer size in Bytes.
598af4a03dfSAugustin Cavalier 	 */
599af4a03dfSAugustin Cavalier 	uint64_t			cmb_size;
600af4a03dfSAugustin Cavalier 
601af4a03dfSAugustin Cavalier 	/*
602af4a03dfSAugustin Cavalier 	 * Current offset of controller memory buffer.
603af4a03dfSAugustin Cavalier 	 */
604af4a03dfSAugustin Cavalier 	uint64_t			cmb_current_offset;
605af4a03dfSAugustin Cavalier 
606af4a03dfSAugustin Cavalier 	/*
607af4a03dfSAugustin Cavalier 	 * Quirks flags.
608af4a03dfSAugustin Cavalier 	 */
609af4a03dfSAugustin Cavalier 	unsigned int			quirks;
610af4a03dfSAugustin Cavalier 
611af4a03dfSAugustin Cavalier 	/*
612af4a03dfSAugustin Cavalier 	 * For controller list.
613af4a03dfSAugustin Cavalier 	 */
614af4a03dfSAugustin Cavalier 	LIST_ENTRY(nvme_ctrlr)		link;
615af4a03dfSAugustin Cavalier 
616af4a03dfSAugustin Cavalier } __attribute__((aligned(PAGE_SIZE)));
617af4a03dfSAugustin Cavalier 
618af4a03dfSAugustin Cavalier /*
619af4a03dfSAugustin Cavalier  * Admin functions.
620af4a03dfSAugustin Cavalier  */
621af4a03dfSAugustin Cavalier extern int nvme_admin_identify_ctrlr(struct nvme_ctrlr *ctrlr,
622af4a03dfSAugustin Cavalier 				     struct nvme_ctrlr_data *cdata);
623af4a03dfSAugustin Cavalier 
624af4a03dfSAugustin Cavalier extern int nvme_admin_get_feature(struct nvme_ctrlr *ctrlr,
625af4a03dfSAugustin Cavalier 				  enum nvme_feat_sel sel,
626af4a03dfSAugustin Cavalier 				  enum nvme_feat feature,
627af4a03dfSAugustin Cavalier 				  uint32_t cdw11, uint32_t *attributes);
628af4a03dfSAugustin Cavalier 
629af4a03dfSAugustin Cavalier extern int nvme_admin_set_feature(struct nvme_ctrlr *ctrlr,
630af4a03dfSAugustin Cavalier 				  bool save,
631af4a03dfSAugustin Cavalier 				  enum nvme_feat feature,
632af4a03dfSAugustin Cavalier 				  uint32_t cdw11, uint32_t cdw12,
633af4a03dfSAugustin Cavalier 				  uint32_t *attributes);
634af4a03dfSAugustin Cavalier 
635af4a03dfSAugustin Cavalier extern int nvme_admin_format_nvm(struct nvme_ctrlr *ctrlr,
636af4a03dfSAugustin Cavalier 				 unsigned int nsid,
637af4a03dfSAugustin Cavalier 				 struct nvme_format *format);
638af4a03dfSAugustin Cavalier 
639af4a03dfSAugustin Cavalier extern int nvme_admin_get_log_page(struct nvme_ctrlr *ctrlr,
640af4a03dfSAugustin Cavalier 				   uint8_t log_page, uint32_t nsid,
641af4a03dfSAugustin Cavalier 				   void *payload, uint32_t payload_size);
642af4a03dfSAugustin Cavalier 
643af4a03dfSAugustin Cavalier extern int nvme_admin_abort_cmd(struct nvme_ctrlr *ctrlr,
644af4a03dfSAugustin Cavalier 				uint16_t cid, uint16_t sqid);
645af4a03dfSAugustin Cavalier 
646af4a03dfSAugustin Cavalier extern int nvme_admin_create_ioq(struct nvme_ctrlr *ctrlr,
647af4a03dfSAugustin Cavalier 				 struct nvme_qpair *io_que,
648af4a03dfSAugustin Cavalier 				 enum nvme_io_queue_type io_qtype);
649af4a03dfSAugustin Cavalier 
650af4a03dfSAugustin Cavalier extern int nvme_admin_delete_ioq(struct nvme_ctrlr *ctrlr,
651af4a03dfSAugustin Cavalier 				 struct nvme_qpair *qpair,
652af4a03dfSAugustin Cavalier 				 enum nvme_io_queue_type io_qtype);
653af4a03dfSAugustin Cavalier 
654af4a03dfSAugustin Cavalier extern int nvme_admin_identify_ns(struct nvme_ctrlr *ctrlr,
655af4a03dfSAugustin Cavalier 				  uint16_t nsid,
656af4a03dfSAugustin Cavalier 				  struct nvme_ns_data *nsdata);
657af4a03dfSAugustin Cavalier 
658af4a03dfSAugustin Cavalier extern int nvme_admin_attach_ns(struct nvme_ctrlr *ctrlr,
659af4a03dfSAugustin Cavalier 				uint32_t nsid,
660af4a03dfSAugustin Cavalier 				struct nvme_ctrlr_list *clist);
661af4a03dfSAugustin Cavalier 
662af4a03dfSAugustin Cavalier extern int nvme_admin_detach_ns(struct nvme_ctrlr *ctrlr,
663af4a03dfSAugustin Cavalier 				uint32_t nsid,
664af4a03dfSAugustin Cavalier 				struct nvme_ctrlr_list *clist);
665af4a03dfSAugustin Cavalier 
666af4a03dfSAugustin Cavalier extern int nvme_admin_create_ns(struct nvme_ctrlr *ctrlr,
667af4a03dfSAugustin Cavalier 				struct nvme_ns_data *nsdata,
668af4a03dfSAugustin Cavalier 				unsigned int *nsid);
669af4a03dfSAugustin Cavalier 
670af4a03dfSAugustin Cavalier extern int nvme_admin_delete_ns(struct nvme_ctrlr *ctrlr,
671af4a03dfSAugustin Cavalier 				unsigned int nsid);
672af4a03dfSAugustin Cavalier 
673af4a03dfSAugustin Cavalier extern int nvme_admin_fw_commit(struct nvme_ctrlr *ctrlr,
674af4a03dfSAugustin Cavalier 				const struct nvme_fw_commit *fw_commit);
675af4a03dfSAugustin Cavalier 
676af4a03dfSAugustin Cavalier extern int nvme_admin_fw_image_dl(struct nvme_ctrlr *ctrlr,
677af4a03dfSAugustin Cavalier 				  void *fw, uint32_t size, uint32_t offset);
678af4a03dfSAugustin Cavalier 
679af4a03dfSAugustin Cavalier extern void nvme_request_completion_poll_cb(void *arg,
680af4a03dfSAugustin Cavalier 					    const struct nvme_cpl *cpl);
681af4a03dfSAugustin Cavalier 
682af4a03dfSAugustin Cavalier extern struct nvme_ctrlr *nvme_ctrlr_attach(struct pci_device *pci_dev,
683af4a03dfSAugustin Cavalier 					    struct nvme_ctrlr_opts *opts);
684af4a03dfSAugustin Cavalier 
685af4a03dfSAugustin Cavalier extern void nvme_ctrlr_detach(struct nvme_ctrlr *ctrlr);
686af4a03dfSAugustin Cavalier 
687af4a03dfSAugustin Cavalier extern int nvme_qpair_construct(struct nvme_ctrlr *ctrlr,
688af4a03dfSAugustin Cavalier 				struct nvme_qpair *qpair, enum nvme_qprio qprio,
689af4a03dfSAugustin Cavalier 				uint16_t entries, uint16_t trackers);
690af4a03dfSAugustin Cavalier 
691af4a03dfSAugustin Cavalier extern void nvme_qpair_destroy(struct nvme_qpair *qpair);
692af4a03dfSAugustin Cavalier extern void nvme_qpair_enable(struct nvme_qpair *qpair);
693af4a03dfSAugustin Cavalier extern void nvme_qpair_disable(struct nvme_qpair *qpair);
694af4a03dfSAugustin Cavalier extern int  nvme_qpair_submit_request(struct nvme_qpair *qpair,
695af4a03dfSAugustin Cavalier 				      struct nvme_request *req);
696af4a03dfSAugustin Cavalier extern void nvme_qpair_reset(struct nvme_qpair *qpair);
697af4a03dfSAugustin Cavalier extern void nvme_qpair_fail(struct nvme_qpair *qpair);
698af4a03dfSAugustin Cavalier 
699af4a03dfSAugustin Cavalier extern int nvme_request_pool_construct(struct nvme_qpair *qpair);
700af4a03dfSAugustin Cavalier 
701af4a03dfSAugustin Cavalier extern void nvme_request_pool_destroy(struct nvme_qpair *qpair);
702af4a03dfSAugustin Cavalier 
703af4a03dfSAugustin Cavalier extern struct nvme_request *nvme_request_allocate(struct nvme_qpair *qpair,
704af4a03dfSAugustin Cavalier 		      const struct nvme_payload *payload, uint32_t payload_size,
705af4a03dfSAugustin Cavalier 		      nvme_cmd_cb cb_fn, void *cb_arg);
706af4a03dfSAugustin Cavalier 
707af4a03dfSAugustin Cavalier extern struct nvme_request *nvme_request_allocate_null(struct nvme_qpair *qpair,
708af4a03dfSAugustin Cavalier 						       nvme_cmd_cb cb_fn,
709af4a03dfSAugustin Cavalier 						       void *cb_arg);
710af4a03dfSAugustin Cavalier 
711af4a03dfSAugustin Cavalier extern struct nvme_request *
712af4a03dfSAugustin Cavalier nvme_request_allocate_contig(struct nvme_qpair *qpair,
713af4a03dfSAugustin Cavalier 			     void *buffer, uint32_t payload_size,
714af4a03dfSAugustin Cavalier 			     nvme_cmd_cb cb_fn, void *cb_arg);
715af4a03dfSAugustin Cavalier 
716af4a03dfSAugustin Cavalier extern void nvme_request_free(struct nvme_request *req);
717a73bad3eSAugustin Cavalier extern void nvme_request_free_locked(struct nvme_request *req);
718af4a03dfSAugustin Cavalier 
719af4a03dfSAugustin Cavalier extern void nvme_request_add_child(struct nvme_request *parent,
720af4a03dfSAugustin Cavalier 				   struct nvme_request *child);
721af4a03dfSAugustin Cavalier 
722af4a03dfSAugustin Cavalier extern void nvme_request_remove_child(struct nvme_request *parent,
723af4a03dfSAugustin Cavalier 				      struct nvme_request *child);
724af4a03dfSAugustin Cavalier 
725af4a03dfSAugustin Cavalier extern unsigned int nvme_ctrlr_get_quirks(struct pci_device *pdev);
726af4a03dfSAugustin Cavalier 
727af4a03dfSAugustin Cavalier extern int nvme_ns_construct(struct nvme_ctrlr *ctrlr,
728af4a03dfSAugustin Cavalier 			     struct nvme_ns *ns, unsigned int id);
729af4a03dfSAugustin Cavalier 
730af4a03dfSAugustin Cavalier /*
731af4a03dfSAugustin Cavalier  * Registers mmio access.
732af4a03dfSAugustin Cavalier  */
733af4a03dfSAugustin Cavalier #define nvme_reg_mmio_read_4(sc, reg)		\
734af4a03dfSAugustin Cavalier 	nvme_mmio_read_4((__u32 *)&(sc)->regs->reg)
735af4a03dfSAugustin Cavalier 
736af4a03dfSAugustin Cavalier #define nvme_reg_mmio_read_8(sc, reg)		\
737af4a03dfSAugustin Cavalier 	nvme_mmio_read_8((__u64 *)&(sc)->regs->reg)
738af4a03dfSAugustin Cavalier 
739af4a03dfSAugustin Cavalier #define nvme_reg_mmio_write_4(sc, reg, val)	\
740af4a03dfSAugustin Cavalier 	nvme_mmio_write_4((__u32 *)&(sc)->regs->reg, val)
741af4a03dfSAugustin Cavalier 
742af4a03dfSAugustin Cavalier #define nvme_reg_mmio_write_8(sc, reg, val)	\
743af4a03dfSAugustin Cavalier 	nvme_mmio_write_8((__u64 *)&(sc)->regs->reg, val)
744af4a03dfSAugustin Cavalier 
745af4a03dfSAugustin Cavalier #endif /* __NVME_INTERNAL_H__ */
746