1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2982388eaSZhikang Zhang /*
3982388eaSZhikang Zhang * Copyright (C) 2017 NXP Semiconductors
4982388eaSZhikang Zhang * Copyright (C) 2017 Bin Meng <bmeng.cn@gmail.com>
5982388eaSZhikang Zhang */
6982388eaSZhikang Zhang
7982388eaSZhikang Zhang #ifndef __DRIVER_NVME_H__
8982388eaSZhikang Zhang #define __DRIVER_NVME_H__
9982388eaSZhikang Zhang
10982388eaSZhikang Zhang #include <asm/io.h>
11982388eaSZhikang Zhang
12982388eaSZhikang Zhang struct nvme_id_power_state {
13982388eaSZhikang Zhang __le16 max_power; /* centiwatts */
14982388eaSZhikang Zhang __u8 rsvd2;
15982388eaSZhikang Zhang __u8 flags;
16982388eaSZhikang Zhang __le32 entry_lat; /* microseconds */
17982388eaSZhikang Zhang __le32 exit_lat; /* microseconds */
18982388eaSZhikang Zhang __u8 read_tput;
19982388eaSZhikang Zhang __u8 read_lat;
20982388eaSZhikang Zhang __u8 write_tput;
21982388eaSZhikang Zhang __u8 write_lat;
22982388eaSZhikang Zhang __le16 idle_power;
23982388eaSZhikang Zhang __u8 idle_scale;
24982388eaSZhikang Zhang __u8 rsvd19;
25982388eaSZhikang Zhang __le16 active_power;
26982388eaSZhikang Zhang __u8 active_work_scale;
27982388eaSZhikang Zhang __u8 rsvd23[9];
28982388eaSZhikang Zhang };
29982388eaSZhikang Zhang
30982388eaSZhikang Zhang enum {
31982388eaSZhikang Zhang NVME_PS_FLAGS_MAX_POWER_SCALE = 1 << 0,
32982388eaSZhikang Zhang NVME_PS_FLAGS_NON_OP_STATE = 1 << 1,
33982388eaSZhikang Zhang };
34982388eaSZhikang Zhang
35982388eaSZhikang Zhang struct nvme_id_ctrl {
36982388eaSZhikang Zhang __le16 vid;
37982388eaSZhikang Zhang __le16 ssvid;
38982388eaSZhikang Zhang char sn[20];
39982388eaSZhikang Zhang char mn[40];
40982388eaSZhikang Zhang char fr[8];
41982388eaSZhikang Zhang __u8 rab;
42982388eaSZhikang Zhang __u8 ieee[3];
43982388eaSZhikang Zhang __u8 mic;
44982388eaSZhikang Zhang __u8 mdts;
45982388eaSZhikang Zhang __u16 cntlid;
46982388eaSZhikang Zhang __u32 ver;
47982388eaSZhikang Zhang __u8 rsvd84[172];
48982388eaSZhikang Zhang __le16 oacs;
49982388eaSZhikang Zhang __u8 acl;
50982388eaSZhikang Zhang __u8 aerl;
51982388eaSZhikang Zhang __u8 frmw;
52982388eaSZhikang Zhang __u8 lpa;
53982388eaSZhikang Zhang __u8 elpe;
54982388eaSZhikang Zhang __u8 npss;
55982388eaSZhikang Zhang __u8 avscc;
56982388eaSZhikang Zhang __u8 apsta;
57982388eaSZhikang Zhang __le16 wctemp;
58982388eaSZhikang Zhang __le16 cctemp;
59982388eaSZhikang Zhang __u8 rsvd270[242];
60982388eaSZhikang Zhang __u8 sqes;
61982388eaSZhikang Zhang __u8 cqes;
62982388eaSZhikang Zhang __u8 rsvd514[2];
63982388eaSZhikang Zhang __le32 nn;
64982388eaSZhikang Zhang __le16 oncs;
65982388eaSZhikang Zhang __le16 fuses;
66982388eaSZhikang Zhang __u8 fna;
67982388eaSZhikang Zhang __u8 vwc;
68982388eaSZhikang Zhang __le16 awun;
69982388eaSZhikang Zhang __le16 awupf;
70982388eaSZhikang Zhang __u8 nvscc;
71982388eaSZhikang Zhang __u8 rsvd531;
72982388eaSZhikang Zhang __le16 acwu;
73982388eaSZhikang Zhang __u8 rsvd534[2];
74982388eaSZhikang Zhang __le32 sgls;
75982388eaSZhikang Zhang __u8 rsvd540[1508];
76982388eaSZhikang Zhang struct nvme_id_power_state psd[32];
77982388eaSZhikang Zhang __u8 vs[1024];
78982388eaSZhikang Zhang };
79982388eaSZhikang Zhang
80982388eaSZhikang Zhang enum {
81982388eaSZhikang Zhang NVME_CTRL_ONCS_COMPARE = 1 << 0,
82982388eaSZhikang Zhang NVME_CTRL_ONCS_WRITE_UNCORRECTABLE = 1 << 1,
83982388eaSZhikang Zhang NVME_CTRL_ONCS_DSM = 1 << 2,
84982388eaSZhikang Zhang NVME_CTRL_VWC_PRESENT = 1 << 0,
85982388eaSZhikang Zhang };
86982388eaSZhikang Zhang
87982388eaSZhikang Zhang struct nvme_lbaf {
88982388eaSZhikang Zhang __le16 ms;
89982388eaSZhikang Zhang __u8 ds;
90982388eaSZhikang Zhang __u8 rp;
91982388eaSZhikang Zhang };
92982388eaSZhikang Zhang
93982388eaSZhikang Zhang struct nvme_id_ns {
94982388eaSZhikang Zhang __le64 nsze;
95982388eaSZhikang Zhang __le64 ncap;
96982388eaSZhikang Zhang __le64 nuse;
97982388eaSZhikang Zhang __u8 nsfeat;
98982388eaSZhikang Zhang __u8 nlbaf;
99982388eaSZhikang Zhang __u8 flbas;
100982388eaSZhikang Zhang __u8 mc;
101982388eaSZhikang Zhang __u8 dpc;
102982388eaSZhikang Zhang __u8 dps;
103982388eaSZhikang Zhang __u8 nmic;
104982388eaSZhikang Zhang __u8 rescap;
105982388eaSZhikang Zhang __u8 fpi;
106982388eaSZhikang Zhang __u8 rsvd33;
107982388eaSZhikang Zhang __le16 nawun;
108982388eaSZhikang Zhang __le16 nawupf;
109982388eaSZhikang Zhang __le16 nacwu;
110982388eaSZhikang Zhang __le16 nabsn;
111982388eaSZhikang Zhang __le16 nabo;
112982388eaSZhikang Zhang __le16 nabspf;
113982388eaSZhikang Zhang __u16 rsvd46;
114982388eaSZhikang Zhang __le64 nvmcap[2];
115982388eaSZhikang Zhang __u8 rsvd64[40];
116982388eaSZhikang Zhang __u8 nguid[16];
117982388eaSZhikang Zhang __u8 eui64[8];
118982388eaSZhikang Zhang struct nvme_lbaf lbaf[16];
119982388eaSZhikang Zhang __u8 rsvd192[192];
120982388eaSZhikang Zhang __u8 vs[3712];
121982388eaSZhikang Zhang };
122982388eaSZhikang Zhang
123982388eaSZhikang Zhang enum {
124982388eaSZhikang Zhang NVME_NS_FEAT_THIN = 1 << 0,
125982388eaSZhikang Zhang NVME_NS_FLBAS_LBA_MASK = 0xf,
126982388eaSZhikang Zhang NVME_NS_FLBAS_META_EXT = 0x10,
127982388eaSZhikang Zhang NVME_LBAF_RP_BEST = 0,
128982388eaSZhikang Zhang NVME_LBAF_RP_BETTER = 1,
129982388eaSZhikang Zhang NVME_LBAF_RP_GOOD = 2,
130982388eaSZhikang Zhang NVME_LBAF_RP_DEGRADED = 3,
131982388eaSZhikang Zhang NVME_NS_DPC_PI_LAST = 1 << 4,
132982388eaSZhikang Zhang NVME_NS_DPC_PI_FIRST = 1 << 3,
133982388eaSZhikang Zhang NVME_NS_DPC_PI_TYPE3 = 1 << 2,
134982388eaSZhikang Zhang NVME_NS_DPC_PI_TYPE2 = 1 << 1,
135982388eaSZhikang Zhang NVME_NS_DPC_PI_TYPE1 = 1 << 0,
136982388eaSZhikang Zhang NVME_NS_DPS_PI_FIRST = 1 << 3,
137982388eaSZhikang Zhang NVME_NS_DPS_PI_MASK = 0x7,
138982388eaSZhikang Zhang NVME_NS_DPS_PI_TYPE1 = 1,
139982388eaSZhikang Zhang NVME_NS_DPS_PI_TYPE2 = 2,
140982388eaSZhikang Zhang NVME_NS_DPS_PI_TYPE3 = 3,
141982388eaSZhikang Zhang };
142982388eaSZhikang Zhang
143982388eaSZhikang Zhang struct nvme_smart_log {
144982388eaSZhikang Zhang __u8 critical_warning;
145982388eaSZhikang Zhang __u8 temperature[2];
146982388eaSZhikang Zhang __u8 avail_spare;
147982388eaSZhikang Zhang __u8 spare_thresh;
148982388eaSZhikang Zhang __u8 percent_used;
149982388eaSZhikang Zhang __u8 rsvd6[26];
150982388eaSZhikang Zhang __u8 data_units_read[16];
151982388eaSZhikang Zhang __u8 data_units_written[16];
152982388eaSZhikang Zhang __u8 host_reads[16];
153982388eaSZhikang Zhang __u8 host_writes[16];
154982388eaSZhikang Zhang __u8 ctrl_busy_time[16];
155982388eaSZhikang Zhang __u8 power_cycles[16];
156982388eaSZhikang Zhang __u8 power_on_hours[16];
157982388eaSZhikang Zhang __u8 unsafe_shutdowns[16];
158982388eaSZhikang Zhang __u8 media_errors[16];
159982388eaSZhikang Zhang __u8 num_err_log_entries[16];
160982388eaSZhikang Zhang __le32 warning_temp_time;
161982388eaSZhikang Zhang __le32 critical_comp_time;
162982388eaSZhikang Zhang __le16 temp_sensor[8];
163982388eaSZhikang Zhang __u8 rsvd216[296];
164982388eaSZhikang Zhang };
165982388eaSZhikang Zhang
166982388eaSZhikang Zhang enum {
167982388eaSZhikang Zhang NVME_SMART_CRIT_SPARE = 1 << 0,
168982388eaSZhikang Zhang NVME_SMART_CRIT_TEMPERATURE = 1 << 1,
169982388eaSZhikang Zhang NVME_SMART_CRIT_RELIABILITY = 1 << 2,
170982388eaSZhikang Zhang NVME_SMART_CRIT_MEDIA = 1 << 3,
171982388eaSZhikang Zhang NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4,
172982388eaSZhikang Zhang };
173982388eaSZhikang Zhang
174982388eaSZhikang Zhang struct nvme_lba_range_type {
175982388eaSZhikang Zhang __u8 type;
176982388eaSZhikang Zhang __u8 attributes;
177982388eaSZhikang Zhang __u8 rsvd2[14];
178982388eaSZhikang Zhang __u64 slba;
179982388eaSZhikang Zhang __u64 nlb;
180982388eaSZhikang Zhang __u8 guid[16];
181982388eaSZhikang Zhang __u8 rsvd48[16];
182982388eaSZhikang Zhang };
183982388eaSZhikang Zhang
184982388eaSZhikang Zhang enum {
185982388eaSZhikang Zhang NVME_LBART_TYPE_FS = 0x01,
186982388eaSZhikang Zhang NVME_LBART_TYPE_RAID = 0x02,
187982388eaSZhikang Zhang NVME_LBART_TYPE_CACHE = 0x03,
188982388eaSZhikang Zhang NVME_LBART_TYPE_SWAP = 0x04,
189982388eaSZhikang Zhang
190982388eaSZhikang Zhang NVME_LBART_ATTRIB_TEMP = 1 << 0,
191982388eaSZhikang Zhang NVME_LBART_ATTRIB_HIDE = 1 << 1,
192982388eaSZhikang Zhang };
193982388eaSZhikang Zhang
194982388eaSZhikang Zhang struct nvme_reservation_status {
195982388eaSZhikang Zhang __le32 gen;
196982388eaSZhikang Zhang __u8 rtype;
197982388eaSZhikang Zhang __u8 regctl[2];
198982388eaSZhikang Zhang __u8 resv5[2];
199982388eaSZhikang Zhang __u8 ptpls;
200982388eaSZhikang Zhang __u8 resv10[13];
201982388eaSZhikang Zhang struct {
202982388eaSZhikang Zhang __le16 cntlid;
203982388eaSZhikang Zhang __u8 rcsts;
204982388eaSZhikang Zhang __u8 resv3[5];
205982388eaSZhikang Zhang __le64 hostid;
206982388eaSZhikang Zhang __le64 rkey;
207982388eaSZhikang Zhang } regctl_ds[];
208982388eaSZhikang Zhang };
209982388eaSZhikang Zhang
210982388eaSZhikang Zhang /* I/O commands */
211982388eaSZhikang Zhang
212982388eaSZhikang Zhang enum nvme_opcode {
213982388eaSZhikang Zhang nvme_cmd_flush = 0x00,
214982388eaSZhikang Zhang nvme_cmd_write = 0x01,
215982388eaSZhikang Zhang nvme_cmd_read = 0x02,
216982388eaSZhikang Zhang nvme_cmd_write_uncor = 0x04,
217982388eaSZhikang Zhang nvme_cmd_compare = 0x05,
218982388eaSZhikang Zhang nvme_cmd_write_zeroes = 0x08,
219982388eaSZhikang Zhang nvme_cmd_dsm = 0x09,
220982388eaSZhikang Zhang nvme_cmd_resv_register = 0x0d,
221982388eaSZhikang Zhang nvme_cmd_resv_report = 0x0e,
222982388eaSZhikang Zhang nvme_cmd_resv_acquire = 0x11,
223982388eaSZhikang Zhang nvme_cmd_resv_release = 0x15,
224982388eaSZhikang Zhang };
225982388eaSZhikang Zhang
226982388eaSZhikang Zhang struct nvme_common_command {
227982388eaSZhikang Zhang __u8 opcode;
228982388eaSZhikang Zhang __u8 flags;
229982388eaSZhikang Zhang __u16 command_id;
230982388eaSZhikang Zhang __le32 nsid;
231982388eaSZhikang Zhang __le32 cdw2[2];
232982388eaSZhikang Zhang __le64 metadata;
233982388eaSZhikang Zhang __le64 prp1;
234982388eaSZhikang Zhang __le64 prp2;
235982388eaSZhikang Zhang __le32 cdw10[6];
236982388eaSZhikang Zhang };
237982388eaSZhikang Zhang
238982388eaSZhikang Zhang struct nvme_rw_command {
239982388eaSZhikang Zhang __u8 opcode;
240982388eaSZhikang Zhang __u8 flags;
241982388eaSZhikang Zhang __u16 command_id;
242982388eaSZhikang Zhang __le32 nsid;
243982388eaSZhikang Zhang __u64 rsvd2;
244982388eaSZhikang Zhang __le64 metadata;
245982388eaSZhikang Zhang __le64 prp1;
246982388eaSZhikang Zhang __le64 prp2;
247982388eaSZhikang Zhang __le64 slba;
248982388eaSZhikang Zhang __le16 length;
249982388eaSZhikang Zhang __le16 control;
250982388eaSZhikang Zhang __le32 dsmgmt;
251982388eaSZhikang Zhang __le32 reftag;
252982388eaSZhikang Zhang __le16 apptag;
253982388eaSZhikang Zhang __le16 appmask;
254982388eaSZhikang Zhang };
255982388eaSZhikang Zhang
256982388eaSZhikang Zhang enum {
257982388eaSZhikang Zhang NVME_RW_LR = 1 << 15,
258982388eaSZhikang Zhang NVME_RW_FUA = 1 << 14,
259982388eaSZhikang Zhang NVME_RW_DSM_FREQ_UNSPEC = 0,
260982388eaSZhikang Zhang NVME_RW_DSM_FREQ_TYPICAL = 1,
261982388eaSZhikang Zhang NVME_RW_DSM_FREQ_RARE = 2,
262982388eaSZhikang Zhang NVME_RW_DSM_FREQ_READS = 3,
263982388eaSZhikang Zhang NVME_RW_DSM_FREQ_WRITES = 4,
264982388eaSZhikang Zhang NVME_RW_DSM_FREQ_RW = 5,
265982388eaSZhikang Zhang NVME_RW_DSM_FREQ_ONCE = 6,
266982388eaSZhikang Zhang NVME_RW_DSM_FREQ_PREFETCH = 7,
267982388eaSZhikang Zhang NVME_RW_DSM_FREQ_TEMP = 8,
268982388eaSZhikang Zhang NVME_RW_DSM_LATENCY_NONE = 0 << 4,
269982388eaSZhikang Zhang NVME_RW_DSM_LATENCY_IDLE = 1 << 4,
270982388eaSZhikang Zhang NVME_RW_DSM_LATENCY_NORM = 2 << 4,
271982388eaSZhikang Zhang NVME_RW_DSM_LATENCY_LOW = 3 << 4,
272982388eaSZhikang Zhang NVME_RW_DSM_SEQ_REQ = 1 << 6,
273982388eaSZhikang Zhang NVME_RW_DSM_COMPRESSED = 1 << 7,
274982388eaSZhikang Zhang NVME_RW_PRINFO_PRCHK_REF = 1 << 10,
275982388eaSZhikang Zhang NVME_RW_PRINFO_PRCHK_APP = 1 << 11,
276982388eaSZhikang Zhang NVME_RW_PRINFO_PRCHK_GUARD = 1 << 12,
277982388eaSZhikang Zhang NVME_RW_PRINFO_PRACT = 1 << 13,
278982388eaSZhikang Zhang };
279982388eaSZhikang Zhang
280982388eaSZhikang Zhang struct nvme_dsm_cmd {
281982388eaSZhikang Zhang __u8 opcode;
282982388eaSZhikang Zhang __u8 flags;
283982388eaSZhikang Zhang __u16 command_id;
284982388eaSZhikang Zhang __le32 nsid;
285982388eaSZhikang Zhang __u64 rsvd2[2];
286982388eaSZhikang Zhang __le64 prp1;
287982388eaSZhikang Zhang __le64 prp2;
288982388eaSZhikang Zhang __le32 nr;
289982388eaSZhikang Zhang __le32 attributes;
290982388eaSZhikang Zhang __u32 rsvd12[4];
291982388eaSZhikang Zhang };
292982388eaSZhikang Zhang
293982388eaSZhikang Zhang enum {
294982388eaSZhikang Zhang NVME_DSMGMT_IDR = 1 << 0,
295982388eaSZhikang Zhang NVME_DSMGMT_IDW = 1 << 1,
296982388eaSZhikang Zhang NVME_DSMGMT_AD = 1 << 2,
297982388eaSZhikang Zhang };
298982388eaSZhikang Zhang
299982388eaSZhikang Zhang struct nvme_dsm_range {
300982388eaSZhikang Zhang __le32 cattr;
301982388eaSZhikang Zhang __le32 nlb;
302982388eaSZhikang Zhang __le64 slba;
303982388eaSZhikang Zhang };
304982388eaSZhikang Zhang
305982388eaSZhikang Zhang /* Admin commands */
306982388eaSZhikang Zhang
307982388eaSZhikang Zhang enum nvme_admin_opcode {
308982388eaSZhikang Zhang nvme_admin_delete_sq = 0x00,
309982388eaSZhikang Zhang nvme_admin_create_sq = 0x01,
310982388eaSZhikang Zhang nvme_admin_get_log_page = 0x02,
311982388eaSZhikang Zhang nvme_admin_delete_cq = 0x04,
312982388eaSZhikang Zhang nvme_admin_create_cq = 0x05,
313982388eaSZhikang Zhang nvme_admin_identify = 0x06,
314982388eaSZhikang Zhang nvme_admin_abort_cmd = 0x08,
315982388eaSZhikang Zhang nvme_admin_set_features = 0x09,
316982388eaSZhikang Zhang nvme_admin_get_features = 0x0a,
317982388eaSZhikang Zhang nvme_admin_async_event = 0x0c,
318982388eaSZhikang Zhang nvme_admin_activate_fw = 0x10,
319982388eaSZhikang Zhang nvme_admin_download_fw = 0x11,
320982388eaSZhikang Zhang nvme_admin_format_nvm = 0x80,
321982388eaSZhikang Zhang nvme_admin_security_send = 0x81,
322982388eaSZhikang Zhang nvme_admin_security_recv = 0x82,
323982388eaSZhikang Zhang };
324982388eaSZhikang Zhang
325982388eaSZhikang Zhang enum {
326982388eaSZhikang Zhang NVME_QUEUE_PHYS_CONTIG = (1 << 0),
327982388eaSZhikang Zhang NVME_CQ_IRQ_ENABLED = (1 << 1),
328982388eaSZhikang Zhang NVME_SQ_PRIO_URGENT = (0 << 1),
329982388eaSZhikang Zhang NVME_SQ_PRIO_HIGH = (1 << 1),
330982388eaSZhikang Zhang NVME_SQ_PRIO_MEDIUM = (2 << 1),
331982388eaSZhikang Zhang NVME_SQ_PRIO_LOW = (3 << 1),
332982388eaSZhikang Zhang NVME_FEAT_ARBITRATION = 0x01,
333982388eaSZhikang Zhang NVME_FEAT_POWER_MGMT = 0x02,
334982388eaSZhikang Zhang NVME_FEAT_LBA_RANGE = 0x03,
335982388eaSZhikang Zhang NVME_FEAT_TEMP_THRESH = 0x04,
336982388eaSZhikang Zhang NVME_FEAT_ERR_RECOVERY = 0x05,
337982388eaSZhikang Zhang NVME_FEAT_VOLATILE_WC = 0x06,
338982388eaSZhikang Zhang NVME_FEAT_NUM_QUEUES = 0x07,
339982388eaSZhikang Zhang NVME_FEAT_IRQ_COALESCE = 0x08,
340982388eaSZhikang Zhang NVME_FEAT_IRQ_CONFIG = 0x09,
341982388eaSZhikang Zhang NVME_FEAT_WRITE_ATOMIC = 0x0a,
342982388eaSZhikang Zhang NVME_FEAT_ASYNC_EVENT = 0x0b,
343982388eaSZhikang Zhang NVME_FEAT_AUTO_PST = 0x0c,
344982388eaSZhikang Zhang NVME_FEAT_SW_PROGRESS = 0x80,
345982388eaSZhikang Zhang NVME_FEAT_HOST_ID = 0x81,
346982388eaSZhikang Zhang NVME_FEAT_RESV_MASK = 0x82,
347982388eaSZhikang Zhang NVME_FEAT_RESV_PERSIST = 0x83,
348982388eaSZhikang Zhang NVME_LOG_ERROR = 0x01,
349982388eaSZhikang Zhang NVME_LOG_SMART = 0x02,
350982388eaSZhikang Zhang NVME_LOG_FW_SLOT = 0x03,
351982388eaSZhikang Zhang NVME_LOG_RESERVATION = 0x80,
352982388eaSZhikang Zhang NVME_FWACT_REPL = (0 << 3),
353982388eaSZhikang Zhang NVME_FWACT_REPL_ACTV = (1 << 3),
354982388eaSZhikang Zhang NVME_FWACT_ACTV = (2 << 3),
355982388eaSZhikang Zhang };
356982388eaSZhikang Zhang
357982388eaSZhikang Zhang struct nvme_identify {
358982388eaSZhikang Zhang __u8 opcode;
359982388eaSZhikang Zhang __u8 flags;
360982388eaSZhikang Zhang __u16 command_id;
361982388eaSZhikang Zhang __le32 nsid;
362982388eaSZhikang Zhang __u64 rsvd2[2];
363982388eaSZhikang Zhang __le64 prp1;
364982388eaSZhikang Zhang __le64 prp2;
365982388eaSZhikang Zhang __le32 cns;
366982388eaSZhikang Zhang __u32 rsvd11[5];
367982388eaSZhikang Zhang };
368982388eaSZhikang Zhang
369982388eaSZhikang Zhang struct nvme_features {
370982388eaSZhikang Zhang __u8 opcode;
371982388eaSZhikang Zhang __u8 flags;
372982388eaSZhikang Zhang __u16 command_id;
373982388eaSZhikang Zhang __le32 nsid;
374982388eaSZhikang Zhang __u64 rsvd2[2];
375982388eaSZhikang Zhang __le64 prp1;
376982388eaSZhikang Zhang __le64 prp2;
377982388eaSZhikang Zhang __le32 fid;
378982388eaSZhikang Zhang __le32 dword11;
379982388eaSZhikang Zhang __u32 rsvd12[4];
380982388eaSZhikang Zhang };
381982388eaSZhikang Zhang
382982388eaSZhikang Zhang struct nvme_create_cq {
383982388eaSZhikang Zhang __u8 opcode;
384982388eaSZhikang Zhang __u8 flags;
385982388eaSZhikang Zhang __u16 command_id;
386982388eaSZhikang Zhang __u32 rsvd1[5];
387982388eaSZhikang Zhang __le64 prp1;
388982388eaSZhikang Zhang __u64 rsvd8;
389982388eaSZhikang Zhang __le16 cqid;
390982388eaSZhikang Zhang __le16 qsize;
391982388eaSZhikang Zhang __le16 cq_flags;
392982388eaSZhikang Zhang __le16 irq_vector;
393982388eaSZhikang Zhang __u32 rsvd12[4];
394982388eaSZhikang Zhang };
395982388eaSZhikang Zhang
396982388eaSZhikang Zhang struct nvme_create_sq {
397982388eaSZhikang Zhang __u8 opcode;
398982388eaSZhikang Zhang __u8 flags;
399982388eaSZhikang Zhang __u16 command_id;
400982388eaSZhikang Zhang __u32 rsvd1[5];
401982388eaSZhikang Zhang __le64 prp1;
402982388eaSZhikang Zhang __u64 rsvd8;
403982388eaSZhikang Zhang __le16 sqid;
404982388eaSZhikang Zhang __le16 qsize;
405982388eaSZhikang Zhang __le16 sq_flags;
406982388eaSZhikang Zhang __le16 cqid;
407982388eaSZhikang Zhang __u32 rsvd12[4];
408982388eaSZhikang Zhang };
409982388eaSZhikang Zhang
410982388eaSZhikang Zhang struct nvme_delete_queue {
411982388eaSZhikang Zhang __u8 opcode;
412982388eaSZhikang Zhang __u8 flags;
413982388eaSZhikang Zhang __u16 command_id;
414982388eaSZhikang Zhang __u32 rsvd1[9];
415982388eaSZhikang Zhang __le16 qid;
416982388eaSZhikang Zhang __u16 rsvd10;
417982388eaSZhikang Zhang __u32 rsvd11[5];
418982388eaSZhikang Zhang };
419982388eaSZhikang Zhang
420982388eaSZhikang Zhang struct nvme_abort_cmd {
421982388eaSZhikang Zhang __u8 opcode;
422982388eaSZhikang Zhang __u8 flags;
423982388eaSZhikang Zhang __u16 command_id;
424982388eaSZhikang Zhang __u32 rsvd1[9];
425982388eaSZhikang Zhang __le16 sqid;
426982388eaSZhikang Zhang __u16 cid;
427982388eaSZhikang Zhang __u32 rsvd11[5];
428982388eaSZhikang Zhang };
429982388eaSZhikang Zhang
430982388eaSZhikang Zhang struct nvme_download_firmware {
431982388eaSZhikang Zhang __u8 opcode;
432982388eaSZhikang Zhang __u8 flags;
433982388eaSZhikang Zhang __u16 command_id;
434982388eaSZhikang Zhang __u32 rsvd1[5];
435982388eaSZhikang Zhang __le64 prp1;
436982388eaSZhikang Zhang __le64 prp2;
437982388eaSZhikang Zhang __le32 numd;
438982388eaSZhikang Zhang __le32 offset;
439982388eaSZhikang Zhang __u32 rsvd12[4];
440982388eaSZhikang Zhang };
441982388eaSZhikang Zhang
442982388eaSZhikang Zhang struct nvme_format_cmd {
443982388eaSZhikang Zhang __u8 opcode;
444982388eaSZhikang Zhang __u8 flags;
445982388eaSZhikang Zhang __u16 command_id;
446982388eaSZhikang Zhang __le32 nsid;
447982388eaSZhikang Zhang __u64 rsvd2[4];
448982388eaSZhikang Zhang __le32 cdw10;
449982388eaSZhikang Zhang __u32 rsvd11[5];
450982388eaSZhikang Zhang };
451982388eaSZhikang Zhang
452982388eaSZhikang Zhang struct nvme_command {
453982388eaSZhikang Zhang union {
454982388eaSZhikang Zhang struct nvme_common_command common;
455982388eaSZhikang Zhang struct nvme_rw_command rw;
456982388eaSZhikang Zhang struct nvme_identify identify;
457982388eaSZhikang Zhang struct nvme_features features;
458982388eaSZhikang Zhang struct nvme_create_cq create_cq;
459982388eaSZhikang Zhang struct nvme_create_sq create_sq;
460982388eaSZhikang Zhang struct nvme_delete_queue delete_queue;
461982388eaSZhikang Zhang struct nvme_download_firmware dlfw;
462982388eaSZhikang Zhang struct nvme_format_cmd format;
463982388eaSZhikang Zhang struct nvme_dsm_cmd dsm;
464982388eaSZhikang Zhang struct nvme_abort_cmd abort;
465982388eaSZhikang Zhang };
466982388eaSZhikang Zhang };
467982388eaSZhikang Zhang
468982388eaSZhikang Zhang enum {
469982388eaSZhikang Zhang NVME_SC_SUCCESS = 0x0,
470982388eaSZhikang Zhang NVME_SC_INVALID_OPCODE = 0x1,
471982388eaSZhikang Zhang NVME_SC_INVALID_FIELD = 0x2,
472982388eaSZhikang Zhang NVME_SC_CMDID_CONFLICT = 0x3,
473982388eaSZhikang Zhang NVME_SC_DATA_XFER_ERROR = 0x4,
474982388eaSZhikang Zhang NVME_SC_POWER_LOSS = 0x5,
475982388eaSZhikang Zhang NVME_SC_INTERNAL = 0x6,
476982388eaSZhikang Zhang NVME_SC_ABORT_REQ = 0x7,
477982388eaSZhikang Zhang NVME_SC_ABORT_QUEUE = 0x8,
478982388eaSZhikang Zhang NVME_SC_FUSED_FAIL = 0x9,
479982388eaSZhikang Zhang NVME_SC_FUSED_MISSING = 0xa,
480982388eaSZhikang Zhang NVME_SC_INVALID_NS = 0xb,
481982388eaSZhikang Zhang NVME_SC_CMD_SEQ_ERROR = 0xc,
482982388eaSZhikang Zhang NVME_SC_SGL_INVALID_LAST = 0xd,
483982388eaSZhikang Zhang NVME_SC_SGL_INVALID_COUNT = 0xe,
484982388eaSZhikang Zhang NVME_SC_SGL_INVALID_DATA = 0xf,
485982388eaSZhikang Zhang NVME_SC_SGL_INVALID_METADATA = 0x10,
486982388eaSZhikang Zhang NVME_SC_SGL_INVALID_TYPE = 0x11,
487982388eaSZhikang Zhang NVME_SC_LBA_RANGE = 0x80,
488982388eaSZhikang Zhang NVME_SC_CAP_EXCEEDED = 0x81,
489982388eaSZhikang Zhang NVME_SC_NS_NOT_READY = 0x82,
490982388eaSZhikang Zhang NVME_SC_RESERVATION_CONFLICT = 0x83,
491982388eaSZhikang Zhang NVME_SC_CQ_INVALID = 0x100,
492982388eaSZhikang Zhang NVME_SC_QID_INVALID = 0x101,
493982388eaSZhikang Zhang NVME_SC_QUEUE_SIZE = 0x102,
494982388eaSZhikang Zhang NVME_SC_ABORT_LIMIT = 0x103,
495982388eaSZhikang Zhang NVME_SC_ABORT_MISSING = 0x104,
496982388eaSZhikang Zhang NVME_SC_ASYNC_LIMIT = 0x105,
497982388eaSZhikang Zhang NVME_SC_FIRMWARE_SLOT = 0x106,
498982388eaSZhikang Zhang NVME_SC_FIRMWARE_IMAGE = 0x107,
499982388eaSZhikang Zhang NVME_SC_INVALID_VECTOR = 0x108,
500982388eaSZhikang Zhang NVME_SC_INVALID_LOG_PAGE = 0x109,
501982388eaSZhikang Zhang NVME_SC_INVALID_FORMAT = 0x10a,
502982388eaSZhikang Zhang NVME_SC_FIRMWARE_NEEDS_RESET = 0x10b,
503982388eaSZhikang Zhang NVME_SC_INVALID_QUEUE = 0x10c,
504982388eaSZhikang Zhang NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d,
505982388eaSZhikang Zhang NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e,
506982388eaSZhikang Zhang NVME_SC_FEATURE_NOT_PER_NS = 0x10f,
507982388eaSZhikang Zhang NVME_SC_FW_NEEDS_RESET_SUBSYS = 0x110,
508982388eaSZhikang Zhang NVME_SC_BAD_ATTRIBUTES = 0x180,
509982388eaSZhikang Zhang NVME_SC_INVALID_PI = 0x181,
510982388eaSZhikang Zhang NVME_SC_READ_ONLY = 0x182,
511982388eaSZhikang Zhang NVME_SC_WRITE_FAULT = 0x280,
512982388eaSZhikang Zhang NVME_SC_READ_ERROR = 0x281,
513982388eaSZhikang Zhang NVME_SC_GUARD_CHECK = 0x282,
514982388eaSZhikang Zhang NVME_SC_APPTAG_CHECK = 0x283,
515982388eaSZhikang Zhang NVME_SC_REFTAG_CHECK = 0x284,
516982388eaSZhikang Zhang NVME_SC_COMPARE_FAILED = 0x285,
517982388eaSZhikang Zhang NVME_SC_ACCESS_DENIED = 0x286,
518982388eaSZhikang Zhang NVME_SC_DNR = 0x4000,
519982388eaSZhikang Zhang };
520982388eaSZhikang Zhang
521982388eaSZhikang Zhang struct nvme_completion {
522982388eaSZhikang Zhang __le32 result; /* Used by admin commands to return data */
523982388eaSZhikang Zhang __u32 rsvd;
524982388eaSZhikang Zhang __le16 sq_head; /* how much of this queue may be reclaimed */
525982388eaSZhikang Zhang __le16 sq_id; /* submission queue that generated this entry */
526982388eaSZhikang Zhang __u16 command_id; /* of the command which completed */
527982388eaSZhikang Zhang __le16 status; /* did the command fail, and if so, why? */
528982388eaSZhikang Zhang };
529982388eaSZhikang Zhang
530982388eaSZhikang Zhang /*
531982388eaSZhikang Zhang * Registers should always be accessed with double word or quad word
532982388eaSZhikang Zhang * accesses. Registers with 64-bit address pointers should be written
533982388eaSZhikang Zhang * to with dword accesses by writing the low dword first (ptr[0]),
534982388eaSZhikang Zhang * then the high dword (ptr[1]) second.
535982388eaSZhikang Zhang */
nvme_readq(__le64 volatile * regs)536982388eaSZhikang Zhang static inline u64 nvme_readq(__le64 volatile *regs)
537982388eaSZhikang Zhang {
538982388eaSZhikang Zhang #if BITS_PER_LONG == 64
539982388eaSZhikang Zhang return readq(regs);
540982388eaSZhikang Zhang #else
541982388eaSZhikang Zhang __u32 *ptr = (__u32 *)regs;
542982388eaSZhikang Zhang u64 val_lo = readl(ptr);
543982388eaSZhikang Zhang u64 val_hi = readl(ptr + 1);
544982388eaSZhikang Zhang
545982388eaSZhikang Zhang return val_lo + (val_hi << 32);
546982388eaSZhikang Zhang #endif
547982388eaSZhikang Zhang }
548982388eaSZhikang Zhang
nvme_writeq(const u64 val,__le64 volatile * regs)549982388eaSZhikang Zhang static inline void nvme_writeq(const u64 val, __le64 volatile *regs)
550982388eaSZhikang Zhang {
551982388eaSZhikang Zhang #if BITS_PER_LONG == 64
552982388eaSZhikang Zhang writeq(val, regs);
553982388eaSZhikang Zhang #else
554982388eaSZhikang Zhang __u32 *ptr = (__u32 *)regs;
555982388eaSZhikang Zhang u32 val_lo = lower_32_bits(val);
556982388eaSZhikang Zhang u32 val_hi = upper_32_bits(val);
557982388eaSZhikang Zhang writel(val_lo, ptr);
558982388eaSZhikang Zhang writel(val_hi, ptr + 1);
559982388eaSZhikang Zhang #endif
560982388eaSZhikang Zhang }
561982388eaSZhikang Zhang
562982388eaSZhikang Zhang struct nvme_bar {
563982388eaSZhikang Zhang __u64 cap; /* Controller Capabilities */
564982388eaSZhikang Zhang __u32 vs; /* Version */
565982388eaSZhikang Zhang __u32 intms; /* Interrupt Mask Set */
566982388eaSZhikang Zhang __u32 intmc; /* Interrupt Mask Clear */
567982388eaSZhikang Zhang __u32 cc; /* Controller Configuration */
568982388eaSZhikang Zhang __u32 rsvd1; /* Reserved */
569982388eaSZhikang Zhang __u32 csts; /* Controller Status */
570982388eaSZhikang Zhang __u32 rsvd2; /* Reserved */
571982388eaSZhikang Zhang __u32 aqa; /* Admin Queue Attributes */
572982388eaSZhikang Zhang __u64 asq; /* Admin SQ Base Address */
573982388eaSZhikang Zhang __u64 acq; /* Admin CQ Base Address */
574982388eaSZhikang Zhang };
575982388eaSZhikang Zhang
576982388eaSZhikang Zhang #define NVME_CAP_MQES(cap) ((cap) & 0xffff)
577982388eaSZhikang Zhang #define NVME_CAP_TIMEOUT(cap) (((cap) >> 24) & 0xff)
578982388eaSZhikang Zhang #define NVME_CAP_STRIDE(cap) (((cap) >> 32) & 0xf)
579982388eaSZhikang Zhang #define NVME_CAP_MPSMIN(cap) (((cap) >> 48) & 0xf)
580982388eaSZhikang Zhang #define NVME_CAP_MPSMAX(cap) (((cap) >> 52) & 0xf)
581982388eaSZhikang Zhang
582982388eaSZhikang Zhang #define NVME_VS(major, minor) (((major) << 16) | ((minor) << 8))
583982388eaSZhikang Zhang
584982388eaSZhikang Zhang enum {
585982388eaSZhikang Zhang NVME_CC_ENABLE = 1 << 0,
586982388eaSZhikang Zhang NVME_CC_CSS_NVM = 0 << 4,
587982388eaSZhikang Zhang NVME_CC_MPS_SHIFT = 7,
588982388eaSZhikang Zhang NVME_CC_ARB_RR = 0 << 11,
589982388eaSZhikang Zhang NVME_CC_ARB_WRRU = 1 << 11,
590982388eaSZhikang Zhang NVME_CC_ARB_VS = 7 << 11,
591982388eaSZhikang Zhang NVME_CC_SHN_NONE = 0 << 14,
592982388eaSZhikang Zhang NVME_CC_SHN_NORMAL = 1 << 14,
593982388eaSZhikang Zhang NVME_CC_SHN_ABRUPT = 2 << 14,
594982388eaSZhikang Zhang NVME_CC_SHN_MASK = 3 << 14,
595982388eaSZhikang Zhang NVME_CC_IOSQES = 6 << 16,
596982388eaSZhikang Zhang NVME_CC_IOCQES = 4 << 20,
597982388eaSZhikang Zhang NVME_CSTS_RDY = 1 << 0,
598982388eaSZhikang Zhang NVME_CSTS_CFS = 1 << 1,
599982388eaSZhikang Zhang NVME_CSTS_SHST_NORMAL = 0 << 2,
600982388eaSZhikang Zhang NVME_CSTS_SHST_OCCUR = 1 << 2,
601982388eaSZhikang Zhang NVME_CSTS_SHST_CMPLT = 2 << 2,
602982388eaSZhikang Zhang NVME_CSTS_SHST_MASK = 3 << 2,
603982388eaSZhikang Zhang };
604982388eaSZhikang Zhang
605982388eaSZhikang Zhang /* Represents an NVM Express device. Each nvme_dev is a PCI function. */
606982388eaSZhikang Zhang struct nvme_dev {
607982388eaSZhikang Zhang struct list_head node;
608982388eaSZhikang Zhang struct nvme_queue **queues;
609982388eaSZhikang Zhang u32 __iomem *dbs;
610982388eaSZhikang Zhang int instance;
611982388eaSZhikang Zhang unsigned queue_count;
612982388eaSZhikang Zhang unsigned online_queues;
613982388eaSZhikang Zhang unsigned max_qid;
614982388eaSZhikang Zhang int q_depth;
615982388eaSZhikang Zhang u32 db_stride;
616982388eaSZhikang Zhang u32 ctrl_config;
617982388eaSZhikang Zhang struct nvme_bar __iomem *bar;
618982388eaSZhikang Zhang struct list_head namespaces;
619982388eaSZhikang Zhang char serial[20];
620982388eaSZhikang Zhang char model[40];
621982388eaSZhikang Zhang char firmware_rev[8];
622982388eaSZhikang Zhang u32 max_transfer_shift;
623b65c6921SBin Meng u64 cap;
624982388eaSZhikang Zhang u32 stripe_size;
625982388eaSZhikang Zhang u32 page_size;
626982388eaSZhikang Zhang u8 vwc;
627982388eaSZhikang Zhang u64 *prp_pool;
628982388eaSZhikang Zhang u32 prp_entry_num;
629982388eaSZhikang Zhang u32 nn;
630982388eaSZhikang Zhang };
631982388eaSZhikang Zhang
632982388eaSZhikang Zhang /*
633982388eaSZhikang Zhang * An NVM Express namespace is equivalent to a SCSI LUN.
634982388eaSZhikang Zhang * Each namespace is operated as an independent "device".
635982388eaSZhikang Zhang */
636982388eaSZhikang Zhang struct nvme_ns {
637982388eaSZhikang Zhang struct list_head list;
638982388eaSZhikang Zhang struct nvme_dev *dev;
639982388eaSZhikang Zhang unsigned ns_id;
640982388eaSZhikang Zhang int devnum;
641982388eaSZhikang Zhang int lba_shift;
642982388eaSZhikang Zhang u8 flbas;
643982388eaSZhikang Zhang u64 mode_select_num_blocks;
644982388eaSZhikang Zhang u32 mode_select_block_len;
645982388eaSZhikang Zhang };
646982388eaSZhikang Zhang
647982388eaSZhikang Zhang #endif /* __DRIVER_NVME_H__ */
648