xref: /openbsd/sys/dev/ic/nvmevar.h (revision f6aab3d8)
1 /*	$OpenBSD: nvmevar.h,v 1.28 2021/08/29 12:02:52 kettenis Exp $ */
2 
3 /*
4  * Copyright (c) 2014 David Gwynne <dlg@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #define NVME_IO_Q	1
20 #define NVME_HIB_Q	2
21 #define NVME_MAXPHYS	(128 * 1024)
22 
23 struct nvme_dmamem {
24 	bus_dmamap_t		ndm_map;
25 	bus_dma_segment_t	ndm_seg;
26 	size_t			ndm_size;
27 	caddr_t			ndm_kva;
28 };
29 #define NVME_DMA_MAP(_ndm)	((_ndm)->ndm_map)
30 #define NVME_DMA_LEN(_ndm)	((_ndm)->ndm_map->dm_segs[0].ds_len)
31 #define NVME_DMA_DVA(_ndm)	((u_int64_t)(_ndm)->ndm_map->dm_segs[0].ds_addr)
32 #define NVME_DMA_KVA(_ndm)	((void *)(_ndm)->ndm_kva)
33 
34 struct nvme_softc;
35 struct nvme_queue;
36 
37 struct nvme_ccb {
38 	SIMPLEQ_ENTRY(nvme_ccb)	ccb_entry;
39 
40 	bus_dmamap_t		ccb_dmamap;
41 
42 	void			*ccb_cookie;
43 	void			(*ccb_done)(struct nvme_softc *sc,
44 				    struct nvme_ccb *, struct nvme_cqe *);
45 
46 	bus_addr_t		ccb_prpl_off;
47 	u_int64_t		ccb_prpl_dva;
48 	u_int64_t		*ccb_prpl;
49 
50 	u_int16_t		ccb_id;
51 };
52 SIMPLEQ_HEAD(nvme_ccb_list, nvme_ccb);
53 
54 struct nvme_queue {
55 	struct mutex		q_sq_mtx;
56 	struct mutex		q_cq_mtx;
57 	struct nvme_dmamem	*q_sq_dmamem;
58 	struct nvme_dmamem	*q_cq_dmamem;
59 	struct nvme_dmamem	*q_nvmmu_dmamem; /* for aplns(4) */
60 	bus_size_t 		q_sqtdbl; /* submission queue tail doorbell */
61 	bus_size_t 		q_cqhdbl; /* completion queue head doorbell */
62 	u_int16_t		q_id;
63 	u_int32_t		q_entries;
64 	u_int32_t		q_sq_tail;
65 	u_int32_t		q_cq_head;
66 	u_int16_t		q_cq_phase;
67 };
68 
69 struct nvme_namespace {
70 	struct nvm_identify_namespace *ident;
71 };
72 
73 struct nvme_ops {
74 	void		(*op_enable)(struct nvme_softc *);
75 
76 	int		(*op_q_alloc)(struct nvme_softc *,
77 			      struct nvme_queue *);
78 	void		(*op_q_free)(struct nvme_softc *,
79 			      struct nvme_queue *);
80 
81 	uint32_t	(*op_sq_enter)(struct nvme_softc *,
82 			      struct nvme_queue *, struct nvme_ccb *);
83 	void		(*op_sq_leave)(struct nvme_softc *,
84 			      struct nvme_queue *, struct nvme_ccb *);
85 	uint32_t	(*op_sq_enter_locked)(struct nvme_softc *,
86 			      struct nvme_queue *, struct nvme_ccb *);
87 	void		(*op_sq_leave_locked)(struct nvme_softc *,
88 			      struct nvme_queue *, struct nvme_ccb *);
89 
90 	void		(*op_cq_done)(struct nvme_softc *,
91 			      struct nvme_queue *, struct nvme_ccb *);
92 };
93 
94 struct nvme_softc {
95 	struct device		sc_dev;
96 
97 	const struct nvme_ops	*sc_ops;
98 	u_int			sc_openings;
99 
100 	bus_space_tag_t		sc_iot;
101 	bus_space_handle_t	sc_ioh;
102 	bus_size_t		sc_ios;
103 	bus_dma_tag_t		sc_dmat;
104 
105 	void			*sc_ih;
106 
107 	u_int			sc_rdy_to;
108 	size_t			sc_mps;
109 	size_t			sc_mdts;
110 	u_int			sc_max_prpl;
111 	u_int			sc_dstrd;
112 
113 	struct nvm_identify_controller
114 				sc_identify;
115 
116 	u_int			sc_nn;
117 	struct nvme_namespace	*sc_namespaces;
118 
119 	struct nvme_queue	*sc_admin_q;
120 	struct nvme_queue	*sc_q;
121 	struct nvme_queue	*sc_hib_q;
122 
123 	struct mutex		sc_ccb_mtx;
124 	struct nvme_ccb		*sc_ccbs;
125 	struct nvme_ccb_list	sc_ccb_list;
126 	struct nvme_dmamem	*sc_ccb_prpls;
127 	struct scsi_iopool	sc_iopool;
128 };
129 
130 #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
131 
132 int	nvme_attach(struct nvme_softc *);
133 int	nvme_activate(struct nvme_softc *, int);
134 int	nvme_intr(void *);
135 int	nvme_intr_intx(void *);
136 
137 #define nvme_read4(_s, _r) \
138 	bus_space_read_4((_s)->sc_iot, (_s)->sc_ioh, (_r))
139 #define nvme_write4(_s, _r, _v) \
140 	bus_space_write_4((_s)->sc_iot, (_s)->sc_ioh, (_r), (_v))
141 
142 u_int64_t
143 	nvme_read8(struct nvme_softc *, bus_size_t);
144 void	nvme_write8(struct nvme_softc *, bus_size_t, u_int64_t);
145 
146 #define nvme_barrier(_s, _r, _l, _f) \
147 	bus_space_barrier((_s)->sc_iot, (_s)->sc_ioh, (_r), (_l), (_f))
148 
149 struct nvme_dmamem *
150 	nvme_dmamem_alloc(struct nvme_softc *, size_t);
151 void	nvme_dmamem_free(struct nvme_softc *, struct nvme_dmamem *);
152 void	nvme_dmamem_sync(struct nvme_softc *, struct nvme_dmamem *, int);
153