xref: /dragonfly/sys/dev/disk/nvme/nvme_ident.h (revision 70394f3fc7eef7464f17a594fdb1761670f93860)
1 /*
2  * Copyright (c) 2016 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
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  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 typedef struct {
36           /* TODO (Fig 91 - Identify Power State Descriptor Data Structure) */
37           uint8_t             filler[32];
38 } __packed nvme_pwstate_data_t;
39 
40 /*
41  * NVME Identify Command data response structures
42  */
43 typedef struct {
44           /*
45            * Controller Capabilities and Features
46            */
47           uint16_t  pci_vendor;
48           uint16_t  pci_subsys;
49           uint8_t             serialno[20];       /* ascii string */
50           uint8_t             modelno[40];        /* ascii string */
51 
52           uint64_t  fwrev;              /* firmware revision */
53           uint8_t             arb_burst;          /* recommended arbitration burst */
54           uint8_t             ieee_oui[3];        /* IEEE OUI identifier */
55           uint8_t             cmic_caps;          /* multi-path / ns sharing caps */
56           uint8_t             mdts;               /* max data xfer size 2^N x mempgsiz */
57 
58           uint16_t  cntlid;             /* unique controller id */
59           uint32_t  vers;               /* (copy of version register) */
60           uint32_t  rtd3r;              /* typical resume latency uS */
61           uint32_t  rtd3e;              /* typical entry latency uS */
62           uint32_t  async_cap;          /* (opt) async capabilities */
63           uint8_t             reserved96[144];
64 
65           char                mgmt_ifc[16];       /* NVMe Manage Interface spec */
66 
67           /*
68            * Admin Command Set Attributes and Optional Controller Capabilities
69            */
70           uint16_t  admin_cap;
71           uint8_t             abort_lim;          /* max concurrent aborts */
72           uint8_t             async_lim;          /* max concurrent async event reqs */
73           uint8_t             fwupd_caps;         /* firmware update capabilities */
74           uint8_t             logpg_attr;
75           uint8_t             logpg_error_entries; /* #of error log ent supported */
76           uint8_t             num_power_states; /* number of power states supported*/
77           uint8_t             avscc;              /* formatting convention for vendor */
78                                                   /* specific commands */
79           uint8_t             apsta;              /* autonomous power states supported */
80           uint16_t  warn_comp_temp;     /* warning comp temp threshold 0=unimp*/
81           uint16_t  crit_comp_temp;     /* warning comp temp threshold 0=unimp*/
82           uint16_t  fw_act_maxtime;     /* max act time N x 100ms, 0=unknown */
83           uint32_t  hmpre;              /* host mem buf requested size */
84           uint32_t  hmmin;              /* host mem buf minimum size */
85           uint64_t  total_capacity[2]; /* 16-byte field, cap in bytes */
86           uint64_t  unalloc_capacity[2]; /* 16-byte field, avail to alloc */
87                                                        /* for namespace attachment */
88 #if _BYTE_ORDER == _LITTLE_ENDIAN
89           uint16_t  reply_flags;
90           uint8_t             replay_tot_size; /* each RPMB in 128KB units, 0=128KB */
91           uint8_t             replay_acc_size; /* each RPMB security send/recv */
92                                                    /*  in 512B units, 0=512B */
93 #else
94           uint8_t             replay_acc_size;
95           uint8_t             replay_tot_size;
96           uint16_t  reply_flags;
97 #endif
98           uint8_t             reserved316[196];
99 
100           /*
101            * NVM Command Set Attributes (starting at offset 512)
102            */
103           uint8_t             subq_entry_size;    /* see defines */
104           uint8_t             comq_entry_size;    /* see defines */
105           uint8_t             reserved514;
106           uint8_t             reserved515;
107           uint32_t  ns_count;           /* number of valid namespaces */
108           uint16_t  nvm_opt_cap;                  /* optional nvm I/O cmds */
109           uint16_t  nvm_fuse_cap;                 /* optional nvm fuse cmds */
110           uint8_t             nvm_format_cap;
111           uint8_t             vwc_flags;                    /* volatile write cache caps */
112           uint16_t  atomic_wun;                   /* atomic write guarantee */
113                                                             /* log blocks, 0 = 1 block */
114           uint16_t  atomic_wupf;                  /* guarante during power fail*/
115                                                             /* log blocks, 0 = 1 block */
116           uint8_t             nvscc;                        /* convention for vendor */
117                                                             /* specific NVM commands */
118           uint8_t             reserved531;
119           uint16_t  atomic_cwu;                   /* atomic comp+write guarantee*/
120           uint16_t  reserved534;
121           uint32_t  sgls;                         /* SGL support */
122           uint8_t             reserved540[164];
123 
124           /*
125            * I/O Command Set Attributes (offset 704)
126            */
127           uint8_t             reserved704[1344];
128 
129           /*
130            * Power State Descriptors (offset 2048)
131            */
132           nvme_pwstate_data_t pwrdescs[32];
133 
134           /*
135            * Vendor Specific (offset 3072)
136            */
137           uint8_t             vendor3072[1024];
138 } __packed nvme_ident_ctlr_data_t;
139 
140 /*
141  * Controller list format
142  */
143 typedef struct {
144           uint16_t  idcount;  /* 2047 max */
145           uint16_t  ctlrids[2047];      /* N controller ids */
146 } __packed nvme_ident_ctlr_list_t;
147 
148 typedef struct {
149           uint32_t  nsids[1024];        /* N namespace ids */
150 } __packed nvme_ident_ns_list_t;
151 
152 #define NVME_CMIC_80                    0x80
153 #define NVME_CMIC_40                    0x40
154 #define NVME_CMIC_20                    0x20
155 #define NVME_CMIC_10                    0x10
156 #define NVME_CMIC_08                    0x08
157 #define NVME_CMIC_CTLR_VIRTUAL          0x04      /* controller assoc w/virtual funct */
158 #define NVME_CMIC_MULTI_CTLR  0x02      /* subsystem has 2+ controllers */
159 #define NVME_CMIC_MULTI_PCI   0x01      /* subsystem has 2+ PCIe ports */
160 
161 #define NVME_ASYNC_NSATTRCHG  0x00000100U /* supports ns attr chg event */
162 
163 #define NVME_ADMIN_NSMANAGE   0x0008U   /* admin_cap */
164 #define NVME_ADMIN_FWIMG      0x0004U
165 #define NVME_ADMIN_FORMAT     0x0002U
166 #define NVME_ADMIN_SECURITY   0x0001U
167 
168 #define NVME_FWUPD_FWACT_NORST          0x10      /* fw activation without reset */
169 #define NVME_FWUPD_SLTCNT_MASK          0x0E      /* fw slots */
170 #define NVME_FWUPD_SLOT1RO    0x01      /* slot 1 (first slot) is RO */
171 
172 #define NVME_FWUPD_SLTCNT_GET(data)     \
173                     (((data) & NVME_FWUPD_SLTCNT_MASK) >> 1)
174 
175 #define NVME_LOGPG_ATTR_CMDEFF          0x02      /* supports command effects log pg */
176 #define NVME_LOGPG_ATTR_SMART 0x01      /* supports SMART log pg */
177 
178 #define NVME_AVSCC_ALLUSEFIG13          0x01      /* all use standard format (fig13) */
179 
180 #define NVME_APSTA_SUPPORTED  0x01      /* supports autonomous transitions */
181 
182 #define NVME_REPLAY_AUTH_MASK 0x0038
183 #define NVME_REPLAY_RPMB_MASK 0x0007
184 
185 #define NVME_REPLAY_RPMB_GET(data)      \
186                     ((data) & NVME_REPLAY_RPMB_MASK)
187 #define NVME_REPLAY_AUTH_GET(data)      \
188                     (((data) & NVME_REPLAY_AUTH_MASK) >> 3)
189 
190 #define NVME_REPLY_AUTH_HMAC_SHA256     0
191                                                   /* 1-7 reserved */
192 
193 /*
194  * Defines for NVM Command set Attributes
195  */
196 #define NVME_QENTRY_MAX_MASK  0xF0      /* subq_entry_size & comq_entry_size */
197 #define NVME_QENTRY_REQ_MASK  0x0F      /* subq_entry_size & comq_entry_size */
198 
199 #define NVME_QENTRY_MAX_GET(data)       \
200                     (1 << (((data) & NVME_QENTRY_MAX_MASK) >> 4))
201 #define NVME_QENTRY_REQ_GET(data)       \
202                     (1 << ((data) & NVME_QENTRY_REQ_MASK))
203 
204 #define NVME_NVMCAP_RESERVATIONS        0x0020
205 #define NVME_NVMCAP_SETFEATSAVE                   0x0010
206 #define NVME_NVMCAP_WRITEZEROS                    0x0008
207 #define NVME_NVMCAP_DSETMGMT            0x0004
208 #define NVME_NVMCAP_WRITEUNCORR                   0x0002
209 #define NVME_NVMCAP_COMPARE             0x0001
210 
211 #define NVME_FUSECAP_CMPWRITE           0x0001
212 
213 #define NVME_FORMATCAP_CRYPTO           0x04      /* supported as part of secure*/
214                                                             /* erase functionality */
215 #define NVME_FORMATCAP_CRYPTOALLNS      0x02      /* crypto erase to all ns's */
216 #define NVME_FORMATCAP_FMTALLNS                   0x01      /* fmt applies to all ns's */
217 
218 #define NVME_VWC_PRESENT                0x01
219 
220 #define NVME_SGLS_EXCESS_SUPP           0x00040000U
221 #define NVME_SGLS_META_BYTE_CONTIG_SUPP 0x00020000U
222 #define NVME_SGLS_BITBUCKET_SUPP        0x00010000U
223 #define NVME_SGLS_NVM_SUPP              0x00000001U
224 
225 /*
226  * For lba_fmt[] field below.
227  *
228  * NOTE: If protection is enabled, the first or last 8 bytes of the meta-data
229  *         holds the protection information (in-band with the meta-data).
230  */
231 typedef struct {
232 #if _BYTE_ORDER == _LITTLE_ENDIAN
233           uint16_t  ms;                 /* meta-dta bytes per lba */
234           uint8_t             sect_size;          /* sector size 1 << n */
235           uint8_t             flags;
236 #else
237           uint8_t             flags;
238           uint8_t             lbads;              /* sector size 1 << n */
239           uint16_t  ms;                 /* meta-dta bytes per lba */
240 #endif
241 } __packed nvme_lba_fmt_data_t;
242 
243 /* flags field */
244 #define NVME_LBAFMT_PERF_MASK           0x03
245 #define NVME_LBAFMT_PERF_BEST           0x00
246 #define NVME_LBAFMT_PERF_BETTER                   0x01
247 #define NVME_LBAFMT_PERF_GOOD           0x02
248 #define NVME_LBAFMT_PERF_DEGRADED       0x03
249 
250 /*
251  * NVME Identify Namespace data response structures (4096 bytes)
252  */
253 typedef struct {
254           uint64_t  size;               /* in logical blocks */
255           uint64_t  capacity; /* in logical blocks (for thin prov) */
256           uint64_t  util;               /* in logical blocks */
257           uint8_t             features;
258           uint8_t             nlbaf;              /* #lba formats avail */
259           uint8_t             flbas;              /* lba fmt used by current ns */
260           uint8_t             mc;                 /* meta-data capabilities */
261           uint8_t             dpc;                /* data-protection caps */
262           uint8_t             dps;                /* data-protection type settings */
263           uint8_t             nmic;               /* (opt) mpath I/O / ns sharing */
264           uint8_t             res_cap;  /* (opt) reservation capabilities */
265           uint8_t             fmt_progress;       /* (opt) format progress */
266           uint8_t             reserved33;
267           uint16_t  natomic_wun;        /* (opt) atomic overrides for ns */
268           uint16_t  natomic_wupf;       /* (opt) atomic overrides for ns */
269           uint16_t  natomic_cwu;        /* (opt) atomic overrides for ns */
270           uint16_t  natomic_bsn;        /* (opt) atomic overrides for ns */
271           uint16_t  natomic_bo;         /* (opt) atomic overrides for ns */
272           uint16_t  natomic_bspf;       /* (opt) atomic overrides for ns */
273           uint16_t  reserved46;
274           uint64_t  nvm_capacity[2];/* (opt) total size in bytes of the */
275                                                   /* nvm allocated to this namespace */
276           uint8_t             reserved64[40];
277           uint64_t  nguid[2]; /* ns global uuid */
278           uint64_t  eui64;              /* ieee ext unique id */
279           nvme_lba_fmt_data_t lba_fmt[16];/* format 0 [0] is mandatory */
280           uint8_t             reserved192[192];
281           uint8_t             reserved384[3712];
282 } __packed nvme_ident_ns_data_t;
283 
284 #define NVME_NSFEAT_DEALLOC             0x04      /* support deallocation */
285 #define NVME_NSFEAT_NATOMICS            0x02      /* use NAWUN, NAWUPF, NACWU */
286 #define NVME_NSFEAT_THIN                0x01      /* thin provisioning avail */
287 
288 #define NVME_FLBAS_META_INLINE                    0x10      /* inline w/data, 0=separate */
289 #define NVME_FLBAS_SEL_MASK             0x0F
290 #define NVME_FLBAS_SEL_GET(data)        \
291                     ((data) & NVME_FLBAS_SEL_MASK)
292 
293 #define NVME_MC_INLINE                            0x02      /* can xfer meta inline */
294 #define NVME_MC_EXTLBA                            0x01      /* can xfer meta separately */
295 
296 
297 #define NVME_DPC_META_L8                0x10
298 #define NVME_DPC_META_F8                0x08
299 #define NVME_DPC_TYPE3                            0x04
300 #define NVME_DPC_TYPE2                            0x02
301 #define NVME_DPC_TYPE1                            0x01
302 
303 #define NVME_DPS_PROT_MASK              0x07
304 
305 #define NVME_DPS_PROT_GET(data)                   \
306                     ((data) & NVME_DPS_PROT_MASK)
307 
308 #define NVME_DPS_PROT_NONE              0
309 #define NVME_DPS_PROT_TYPE1             1
310 #define NVME_DPS_PROT_TYPE2             2
311 #define NVME_DPS_PROT_TYPE3             3
312                                                   /* 4-7 reserved */
313 
314 #define NVME_NMIC_SHARED                0x01
315