xref: /freebsd/sys/dev/nvme/nvme_private.h (revision 724b4bfdf1306e4f2c451b6d146fe0fe0353b2c8)
1 /*-
2  * Copyright (C) 2012 Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #ifndef __NVME_PRIVATE_H__
30 #define __NVME_PRIVATE_H__
31 
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/lock.h>
35 #include <sys/malloc.h>
36 #include <sys/mutex.h>
37 #include <sys/rman.h>
38 #include <sys/systm.h>
39 #include <sys/taskqueue.h>
40 
41 #include <vm/uma.h>
42 
43 #include <machine/bus.h>
44 
45 #include "nvme.h"
46 
47 #define DEVICE2SOFTC(dev) ((struct nvme_controller *) device_get_softc(dev))
48 
49 MALLOC_DECLARE(M_NVME);
50 
51 #define CHATHAM2
52 
53 #ifdef CHATHAM2
54 #define CHATHAM_PCI_ID		0x20118086
55 #define CHATHAM_CONTROL_BAR	0
56 #endif
57 
58 #define IDT_PCI_ID		0x80d0111d
59 
60 #define NVME_MAX_PRP_LIST_ENTRIES	(32)
61 
62 /*
63  * For commands requiring more than 2 PRP entries, one PRP will be
64  *  embedded in the command (prp1), and the rest of the PRP entries
65  *  will be in a list pointed to by the command (prp2).  This means
66  *  that real max number of PRP entries we support is 32+1, which
67  *  results in a max xfer size of 32*PAGE_SIZE.
68  */
69 #define NVME_MAX_XFER_SIZE	NVME_MAX_PRP_LIST_ENTRIES * PAGE_SIZE
70 
71 #define NVME_ADMIN_TRACKERS	(16)
72 #define NVME_ADMIN_ENTRIES	(128)
73 /* min and max are defined in admin queue attributes section of spec */
74 #define NVME_MIN_ADMIN_ENTRIES	(2)
75 #define NVME_MAX_ADMIN_ENTRIES	(4096)
76 
77 /*
78  * NVME_IO_ENTRIES defines the size of an I/O qpair's submission and completion
79  *  queues, while NVME_IO_TRACKERS defines the maximum number of I/O that we
80  *  will allow outstanding on an I/O qpair at any time.  The only advantage in
81  *  having IO_ENTRIES > IO_TRACKERS is for debugging purposes - when dumping
82  *  the contents of the submission and completion queues, it will show a longer
83  *  history of data.
84  */
85 #define NVME_IO_ENTRIES		(256)
86 #define NVME_IO_TRACKERS	(128)
87 #define NVME_MIN_IO_TRACKERS	(16)
88 #define NVME_MAX_IO_TRACKERS	(1024)
89 
90 /*
91  * NVME_MAX_IO_ENTRIES is not defined, since it is specified in CC.MQES
92  *  for each controller.
93  */
94 
95 #define NVME_INT_COAL_TIME	(0)	/* disabled */
96 #define NVME_INT_COAL_THRESHOLD (0)	/* 0-based */
97 
98 #define NVME_MAX_NAMESPACES	(16)
99 #define NVME_MAX_CONSUMERS	(2)
100 #define NVME_MAX_ASYNC_EVENTS	(4)
101 
102 #define NVME_TIMEOUT_IN_SEC	(30)
103 
104 #ifndef CACHE_LINE_SIZE
105 #define CACHE_LINE_SIZE		(64)
106 #endif
107 
108 extern uma_zone_t nvme_request_zone;
109 
110 struct nvme_request {
111 
112 	struct nvme_command		cmd;
113 	void				*payload;
114 	uint32_t			payload_size;
115 	struct uio			*uio;
116 	nvme_cb_fn_t			cb_fn;
117 	void				*cb_arg;
118 	STAILQ_ENTRY(nvme_request)	stailq;
119 };
120 
121 struct nvme_tracker {
122 
123 	SLIST_ENTRY(nvme_tracker)	slist;
124 	struct nvme_request		*req;
125 	struct nvme_qpair		*qpair;
126 	struct callout			timer;
127 	bus_dmamap_t			payload_dma_map;
128 	uint16_t			cid;
129 
130 	uint64_t			prp[NVME_MAX_PRP_LIST_ENTRIES];
131 	bus_addr_t			prp_bus_addr;
132 	bus_dmamap_t			prp_dma_map;
133 };
134 
135 struct nvme_qpair {
136 
137 	struct nvme_controller	*ctrlr;
138 	uint32_t		id;
139 	uint32_t		phase;
140 
141 	uint16_t		vector;
142 	int			rid;
143 	struct resource		*res;
144 	void 			*tag;
145 
146 	uint32_t		max_xfer_size;
147 	uint32_t		num_entries;
148 	uint32_t		num_trackers;
149 	uint32_t		sq_tdbl_off;
150 	uint32_t		cq_hdbl_off;
151 
152 	uint32_t		sq_head;
153 	uint32_t		sq_tail;
154 	uint32_t		cq_head;
155 
156 	int64_t			num_cmds;
157 	int64_t			num_intr_handler_calls;
158 
159 	struct nvme_command	*cmd;
160 	struct nvme_completion	*cpl;
161 
162 	bus_dma_tag_t		dma_tag;
163 
164 	bus_dmamap_t		cmd_dma_map;
165 	uint64_t		cmd_bus_addr;
166 
167 	bus_dmamap_t		cpl_dma_map;
168 	uint64_t		cpl_bus_addr;
169 
170 	SLIST_HEAD(, nvme_tracker)	free_tr;
171 	STAILQ_HEAD(, nvme_request)	queued_req;
172 
173 	struct nvme_tracker	**act_tr;
174 
175 	struct mtx		lock __aligned(CACHE_LINE_SIZE);
176 
177 } __aligned(CACHE_LINE_SIZE);
178 
179 struct nvme_namespace {
180 
181 	struct nvme_controller		*ctrlr;
182 	struct nvme_namespace_data	data;
183 	uint16_t			id;
184 	uint16_t			flags;
185 	struct cdev			*cdev;
186 };
187 
188 /*
189  * One of these per allocated PCI device.
190  */
191 struct nvme_controller {
192 
193 	device_t		dev;
194 
195 	uint32_t		ready_timeout_in_ms;
196 
197 	bus_space_tag_t		bus_tag;
198 	bus_space_handle_t	bus_handle;
199 	int			resource_id;
200 	struct resource		*resource;
201 
202 #ifdef CHATHAM2
203 	bus_space_tag_t		chatham_bus_tag;
204 	bus_space_handle_t	chatham_bus_handle;
205 	int			chatham_resource_id;
206 	struct resource		*chatham_resource;
207 #endif
208 
209 	uint32_t		msix_enabled;
210 	uint32_t		force_intx;
211 
212 	uint32_t		num_io_queues;
213 	boolean_t		per_cpu_io_queues;
214 
215 	/* Fields for tracking progress during controller initialization. */
216 	struct intr_config_hook	config_hook;
217 	uint32_t		ns_identified;
218 	uint32_t		queues_created;
219 
220 	/* For shared legacy interrupt. */
221 	int			rid;
222 	struct resource		*res;
223 	void			*tag;
224 	struct task		task;
225 	struct taskqueue	*taskqueue;
226 
227 	bus_dma_tag_t		hw_desc_tag;
228 	bus_dmamap_t		hw_desc_map;
229 
230 	/** maximum i/o size in bytes */
231 	uint32_t		max_xfer_size;
232 
233 	/** interrupt coalescing time period (in microseconds) */
234 	uint32_t		int_coal_time;
235 
236 	/** interrupt coalescing threshold */
237 	uint32_t		int_coal_threshold;
238 
239 	struct nvme_qpair	adminq;
240 	struct nvme_qpair	*ioq;
241 
242 	struct nvme_registers		*regs;
243 
244 	struct nvme_controller_data	cdata;
245 	struct nvme_namespace		ns[NVME_MAX_NAMESPACES];
246 
247 	struct cdev			*cdev;
248 
249 	boolean_t			is_started;
250 
251 #ifdef CHATHAM2
252 	uint64_t		chatham_size;
253 	uint64_t		chatham_lbas;
254 #endif
255 };
256 
257 #define nvme_mmio_offsetof(reg)						       \
258 	offsetof(struct nvme_registers, reg)
259 
260 #define nvme_mmio_read_4(sc, reg)					       \
261 	bus_space_read_4((sc)->bus_tag, (sc)->bus_handle,		       \
262 	    nvme_mmio_offsetof(reg))
263 
264 #define nvme_mmio_write_4(sc, reg, val)					       \
265 	bus_space_write_4((sc)->bus_tag, (sc)->bus_handle,		       \
266 	    nvme_mmio_offsetof(reg), val)
267 
268 #define nvme_mmio_write_8(sc, reg, val) \
269 	do {								       \
270 		bus_space_write_4((sc)->bus_tag, (sc)->bus_handle,	       \
271 		    nvme_mmio_offsetof(reg), val & 0xFFFFFFFF); 	       \
272 		bus_space_write_4((sc)->bus_tag, (sc)->bus_handle,	       \
273 		    nvme_mmio_offsetof(reg)+4,				       \
274 		    (val & 0xFFFFFFFF00000000UL) >> 32);		       \
275 	} while (0);
276 
277 #ifdef CHATHAM2
278 #define chatham_read_4(softc, reg) \
279 	bus_space_read_4((softc)->chatham_bus_tag,			       \
280 	    (softc)->chatham_bus_handle, reg)
281 
282 #define chatham_write_8(sc, reg, val)					       \
283 	do {								       \
284 		bus_space_write_4((sc)->chatham_bus_tag,		       \
285 		    (sc)->chatham_bus_handle, reg, val & 0xffffffff);	       \
286 		bus_space_write_4((sc)->chatham_bus_tag,		       \
287 		    (sc)->chatham_bus_handle, reg+4,			       \
288 		    (val & 0xFFFFFFFF00000000UL) >> 32);		       \
289 	} while (0);
290 
291 #endif /* CHATHAM2 */
292 
293 #if __FreeBSD_version < 800054
294 #define wmb()	__asm volatile("sfence" ::: "memory")
295 #define mb()	__asm volatile("mfence" ::: "memory")
296 #endif
297 
298 void	nvme_ns_test(struct nvme_namespace *ns, u_long cmd, caddr_t arg);
299 
300 void	nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
301 				   uint8_t feature, uint32_t cdw11,
302 				   void *payload, uint32_t payload_size,
303 				   nvme_cb_fn_t cb_fn, void *cb_arg);
304 void	nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr,
305 				   uint8_t feature, uint32_t cdw11,
306 				   void *payload, uint32_t payload_size,
307 				   nvme_cb_fn_t cb_fn, void *cb_arg);
308 void	nvme_ctrlr_cmd_identify_controller(struct nvme_controller *ctrlr,
309 					   void *payload,
310 					   nvme_cb_fn_t cb_fn, void *cb_arg);
311 void	nvme_ctrlr_cmd_identify_namespace(struct nvme_controller *ctrlr,
312 					  uint16_t nsid, void *payload,
313 					  nvme_cb_fn_t cb_fn, void *cb_arg);
314 void	nvme_ctrlr_cmd_set_interrupt_coalescing(struct nvme_controller *ctrlr,
315 						uint32_t microseconds,
316 						uint32_t threshold,
317 						nvme_cb_fn_t cb_fn,
318 						void *cb_arg);
319 void	nvme_ctrlr_cmd_get_health_information_page(struct nvme_controller *ctrlr,
320 						   uint32_t nsid,
321 						   struct nvme_health_information_page *payload,
322 						   nvme_cb_fn_t cb_fn,
323 						   void *cb_arg);
324 void	nvme_ctrlr_cmd_create_io_cq(struct nvme_controller *ctrlr,
325 				    struct nvme_qpair *io_que, uint16_t vector,
326 				    nvme_cb_fn_t cb_fn, void *cb_arg);
327 void	nvme_ctrlr_cmd_create_io_sq(struct nvme_controller *ctrlr,
328 				    struct nvme_qpair *io_que,
329 				    nvme_cb_fn_t cb_fn, void *cb_arg);
330 void	nvme_ctrlr_cmd_delete_io_cq(struct nvme_controller *ctrlr,
331 				    struct nvme_qpair *io_que,
332 				    nvme_cb_fn_t cb_fn, void *cb_arg);
333 void	nvme_ctrlr_cmd_delete_io_sq(struct nvme_controller *ctrlr,
334 				    struct nvme_qpair *io_que,
335 				    nvme_cb_fn_t cb_fn, void *cb_arg);
336 void	nvme_ctrlr_cmd_set_num_queues(struct nvme_controller *ctrlr,
337 				      uint32_t num_queues, nvme_cb_fn_t cb_fn,
338 				      void *cb_arg);
339 void	nvme_ctrlr_cmd_set_asynchronous_event_config(struct nvme_controller *ctrlr,
340 					   union nvme_critical_warning_state state,
341 					   nvme_cb_fn_t cb_fn, void *cb_arg);
342 void	nvme_ctrlr_cmd_asynchronous_event_request(struct nvme_controller *ctrlr,
343 						  nvme_cb_fn_t cb_fn,
344 						  void *cb_arg);
345 
346 void	nvme_payload_map(void *arg, bus_dma_segment_t *seg, int nseg,
347 			 int error);
348 void	nvme_payload_map_uio(void *arg, bus_dma_segment_t *seg, int nseg,
349 			     bus_size_t mapsize, int error);
350 
351 int	nvme_ctrlr_construct(struct nvme_controller *ctrlr, device_t dev);
352 int	nvme_ctrlr_reset(struct nvme_controller *ctrlr);
353 /* ctrlr defined as void * to allow use with config_intrhook. */
354 void	nvme_ctrlr_start(void *ctrlr_arg);
355 void	nvme_ctrlr_submit_admin_request(struct nvme_controller *ctrlr,
356 					struct nvme_request *req);
357 void	nvme_ctrlr_submit_io_request(struct nvme_controller *ctrlr,
358 				     struct nvme_request *req);
359 
360 void	nvme_qpair_construct(struct nvme_qpair *qpair, uint32_t id,
361 			     uint16_t vector, uint32_t num_entries,
362 			     uint32_t num_trackers, uint32_t max_xfer_size,
363 			     struct nvme_controller *ctrlr);
364 void	nvme_qpair_submit_cmd(struct nvme_qpair *qpair,
365 			      struct nvme_tracker *tr);
366 void	nvme_qpair_process_completions(struct nvme_qpair *qpair);
367 void	nvme_qpair_submit_request(struct nvme_qpair *qpair,
368 				  struct nvme_request *req);
369 
370 void	nvme_admin_qpair_destroy(struct nvme_qpair *qpair);
371 
372 void	nvme_io_qpair_destroy(struct nvme_qpair *qpair);
373 
374 int	nvme_ns_construct(struct nvme_namespace *ns, uint16_t id,
375 			  struct nvme_controller *ctrlr);
376 
377 int	nvme_ns_physio(struct cdev *dev, struct uio *uio, int ioflag);
378 
379 void	nvme_sysctl_initialize_ctrlr(struct nvme_controller *ctrlr);
380 
381 void	nvme_dump_command(struct nvme_command *cmd);
382 void	nvme_dump_completion(struct nvme_completion *cpl);
383 
384 static __inline void
385 nvme_single_map(void *arg, bus_dma_segment_t *seg, int nseg, int error)
386 {
387 	uint64_t *bus_addr = (uint64_t *)arg;
388 
389 	*bus_addr = seg[0].ds_addr;
390 }
391 
392 static __inline struct nvme_request *
393 nvme_allocate_request(void *payload, uint32_t payload_size, nvme_cb_fn_t cb_fn,
394 		      void *cb_arg)
395 {
396 	struct nvme_request *req;
397 
398 	req = uma_zalloc(nvme_request_zone, M_NOWAIT | M_ZERO);
399 	if (req == NULL)
400 		return (NULL);
401 
402 	req->payload = payload;
403 	req->payload_size = payload_size;
404 	req->cb_fn = cb_fn;
405 	req->cb_arg = cb_arg;
406 
407 	return (req);
408 }
409 
410 static __inline struct nvme_request *
411 nvme_allocate_request_uio(struct uio *uio, nvme_cb_fn_t cb_fn, void *cb_arg)
412 {
413 	struct nvme_request *req;
414 
415 	req = uma_zalloc(nvme_request_zone, M_NOWAIT | M_ZERO);
416 	if (req == NULL)
417 		return (NULL);
418 
419 	req->uio = uio;
420 	req->cb_fn = cb_fn;
421 	req->cb_arg = cb_arg;
422 
423 	return (req);
424 }
425 
426 #define nvme_free_request(req)	uma_zfree(nvme_request_zone, req)
427 
428 #endif /* __NVME_PRIVATE_H__ */
429