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 */ 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 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