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