1 /* $NetBSD: nvmeio.h,v 1.4 2021/11/10 17:19:30 msaitoh Exp $ */
2
3 /*-
4 * Copyright (C) 2012-2013 Intel Corporation
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/dev/nvme/nvme.h 329824 2018-02-22 13:32:31Z wma $
29 */
30
31 #ifndef __NVMEIO_H__
32 #define __NVMEIO_H__
33
34 #include <sys/endian.h>
35 #include <sys/ioccom.h>
36 #include <dev/ic/nvmereg.h>
37
38 #define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command)
39
40 #define nvme_completion_is_error(cpl) \
41 ((NVME_CQE_SC((cpl)->flags) != NVME_CQE_SC_SUCCESS) \
42 || (NVME_CQE_SCT((cpl)->flags) != NVME_CQE_SCT_GENERIC))
43
44 struct nvme_pt_command {
45
46 /*
47 * cmd is used to specify a passthrough command to a controller or
48 * namespace.
49 *
50 * The following fields from cmd may be specified by the caller:
51 * * opcode
52 * * nsid (namespace id) - for admin commands only
53 * * cdw10-cdw15
54 *
55 * Remaining fields must be set to 0 by the caller.
56 */
57 struct nvme_sqe cmd;
58
59 /*
60 * cpl returns completion status for the passthrough command
61 * specified by cmd.
62 *
63 * The following fields will be filled out by the driver, for
64 * consumption by the caller:
65 * * cdw0
66 * * flags (except for phase)
67 *
68 * Remaining fields will be set to 0 by the driver.
69 */
70 struct nvme_cqe cpl;
71
72 /* buf is the data buffer associated with this passthrough command. */
73 void *buf;
74
75 /*
76 * len is the length of the data buffer associated with this
77 * passthrough command.
78 */
79 uint32_t len;
80
81 /*
82 * is_read = 1 if the passthrough command will read data into the
83 * supplied buffer from the controller.
84 *
85 * is_read = 0 if the passthrough command will write data from the
86 * supplied buffer to the controller.
87 */
88 uint32_t is_read;
89
90 /*
91 * timeout (unit: ms)
92 *
93 * 0: use default timeout value
94 */
95 uint32_t timeout;
96 };
97
98 /* Endianness conversion functions for NVMe structs */
99 static __inline void
nvme_le128toh(uint64_t v[2])100 nvme_le128toh(uint64_t v[2])
101 {
102 #if _BYTE_ORDER != _LITTLE_ENDIAN
103 uint64_t t;
104
105 t = le64toh(v[0]);
106 v[0] = le64toh(v[1]);
107 v[1] = t;
108 #endif
109 }
110
111 static __inline void
nvme_namespace_format_swapbytes(struct nvm_namespace_format * format)112 nvme_namespace_format_swapbytes(struct nvm_namespace_format *format)
113 {
114
115 #if _BYTE_ORDER != _LITTLE_ENDIAN
116 format->ms = le16toh(format->ms);
117 #endif
118 }
119
120 static __inline void
nvme_identify_namespace_swapbytes(struct nvm_identify_namespace * identify)121 nvme_identify_namespace_swapbytes(struct nvm_identify_namespace *identify)
122 {
123 #if _BYTE_ORDER != _LITTLE_ENDIAN
124 u_int i;
125
126 identify->nsze = le64toh(identify->nsze);
127 identify->ncap = le64toh(identify->ncap);
128 identify->nuse = le64toh(identify->nuse);
129 identify->nawun = le16toh(identify->nawun);
130 identify->nawupf = le16toh(identify->nawupf);
131 identify->nacwu = le16toh(identify->nacwu);
132 identify->nabsn = le16toh(identify->nabsn);
133 identify->nabo = le16toh(identify->nabo);
134 identify->nabspf = le16toh(identify->nabspf);
135 identify->noiob = le16toh(identify->noiob);
136 for (i = 0; i < __arraycount(identify->lbaf); i++)
137 nvme_namespace_format_swapbytes(&identify->lbaf[i]);
138 #endif
139 }
140
141 static __inline void
nvme_identify_psd_swapbytes(struct nvm_identify_psd * psd)142 nvme_identify_psd_swapbytes(struct nvm_identify_psd *psd)
143 {
144
145 #if _BYTE_ORDER != _LITTLE_ENDIAN
146 psd->mp = le16toh(psd->mp);
147 psd->enlat = le32toh(psd->enlat);
148 psd->exlat = le32toh(psd->exlat);
149 psd->idlp = le16toh(psd->idlp);
150 psd->actp = le16toh(psd->actp);
151 psd->ap = le16toh(psd->ap);
152 #endif
153 }
154
155 static __inline void
nvme_identify_controller_swapbytes(struct nvm_identify_controller * identify)156 nvme_identify_controller_swapbytes(struct nvm_identify_controller *identify)
157 {
158 #if _BYTE_ORDER != _LITTLE_ENDIAN
159 u_int i;
160
161 identify->vid = le16toh(identify->vid);
162 identify->ssvid = le16toh(identify->ssvid);
163 identify->cntlid = le16toh(identify->cntlid);
164 identify->ver = le32toh(identify->ver);
165 identify->rtd3r = le32toh(identify->rtd3r);
166 identify->rtd3e = le32toh(identify->rtd3e);
167 identify->oaes = le32toh(identify->oaes);
168 identify->ctrattr = le32toh(identify->ctrattr);
169 identify->oacs = le16toh(identify->oacs);
170 identify->wctemp = le16toh(identify->wctemp);
171 identify->cctemp = le16toh(identify->cctemp);
172 identify->mtfa = le16toh(identify->mtfa);
173 identify->hmpre = le32toh(identify->hmpre);
174 identify->hmmin = le32toh(identify->hmmin);
175 nvme_le128toh(identify->untncap.tnvmcap);
176 nvme_le128toh(identify->untncap.unvmcap);
177 identify->rpmbs = le32toh(identify->rpmbs);
178 identify->edstt = le16toh(identify->edstt);
179 identify->kas = le16toh(identify->kas);
180 identify->hctma = le16toh(identify->hctma);
181 identify->mntmt = le16toh(identify->mntmt);
182 identify->mxtmt = le16toh(identify->mxtmt);
183 identify->sanicap = le32toh(identify->sanicap);
184 identify->maxcmd = le16toh(identify->maxcmd);
185 identify->nn = le32toh(identify->nn);
186 identify->oncs = le16toh(identify->oncs);
187 identify->fuses = le16toh(identify->fuses);
188 identify->awun = le16toh(identify->awun);
189 identify->awupf = le16toh(identify->awupf);
190 identify->acwu = le16toh(identify->acwu);
191 identify->sgls = le32toh(identify->sgls);
192 for (i = 0; i < __arraycount(identify->psd); i++)
193 nvme_identify_psd_swapbytes(&identify->psd[i]);
194 #endif
195 }
196
197 #endif /* __NVMEIO_H__ */
198